2016-01-25 3 views
0

Я пытаюсь использовать функцию MATLAB integral() для интеграции по одному параметру кусочно-линейной функции, представляющей изменяющееся во времени значение.Использование интеграла MATLAB с анонимными функциями

Я хотел бы определить анонимную функцию, основанную на исходной функции:

t1 = 1; 
t2 = 2; 
t3 = 4; 
t4 = 5; 

a0 = 1; 
a1 = 2; 

f = @(x) accel_profile(t1,t2,t3,t4,a0,a1,x); 

и вот accel_profile.m:

function value = accel_profile(t1,t2,t3,t4,a0,a1, t) 

if t <= t1 
    value = a0; 
    return 
elseif (t <= t2) 
    value = ((t-t1)/(t2-t1)) * (a1-a0) + a0; 
    return 
elseif (t <= t3) 
    value = a1; 
    return 
elseif (t <= t4) 
    value = ((t-t3)/(t4-t3)) * (a0-a1) + a1; 
    return 
else 
    value = a0; 
    return 
end 

Проблема заключается в том, что, когда я тренируюсь следующий сценарий :

t_list = 0:0.1:6; 
q = zeros(1,length(t_list)) 
for i = 1:length(t_list) 
    q(i) = integral(f,0,t_list(i)); 
end 

plot(t_list, q) 

я получаю следующую трассировку стека:

Error using integralCalc/finalInputChecks (line 515) 
Output of the function must be the same size as the input. If FUN is an array-valued integrand, set 
the 'ArrayValued' option to true. 
Error in integralCalc/iterateScalarValued (line 315) 
       finalInputChecks(x,fx); 
Error in integralCalc/vadapt (line 132) 
      [q,errbnd] = iterateScalarValued(u,tinterval,pathlen); 
Error in integralCalc (line 75) 
     [q,errbnd] = vadapt(@AtoBInvTransform,interval); 
Error in integral (line 88) 
Q = integralCalc(fun,a,b,opstruct); 
515    error(message('MATLAB:integral:FxNotSameSizeAsX')); 

Я бегу MATLAB 2015b на Windows 7.

ответ

5

Проблема заключается в том integral использует векторизованные аргументы для функции, но ваша функция не поддерживает его.

Соответствующая часть из документации:

Для задач скалярных, функция у = весело (х) должен принять вектор аргументов, х и возвращает вектор результата, у. Это обычно означает, что забава должна использовать операторы массива вместо матричных операторов. Например, используйте. * (Times), а не * (mtimes). Если вы установите для параметра «ArrayValued» значение true, то fun должен принять скаляр и вернуть массив фиксированного размера.

Reference

Это означает, что интеграл будет вызывать вашу функцию f с аргументами как f([1,2,3]) и ожидает, что список с [f(1),f(2),f(3)]

Общие методы to vectorize a piecewise defined function are explained in this question

+1

ЗВС, бить меня к нему :(Он должен также работают, чтобы установить «ArrayValued» в true: тогда функция вызывается только со скалярными аргументами. Тогда вам не нужно векторизовать (но вы должны это сделать намного быстрее). –

+2

@AndrasDeak: Я думал, что опция предназначена для функций, возвращающих векторы, я не использовал ее в качестве conciser. Моя версия Matlab старая, чтобы иметь этот вариант, если он действительно решает, напишите ответ. – Daniel

+1

Настройка «ArrayValued» на «true» сделала трюк, спасибо! Я читал это и думал, что это только для функций, возвращающих значения массива, поэтому мой плохой! – gariepy

Смежные вопросы