Интегрирование по постоянной функции

Я пытаюсь интегрировать постоянную функцию в MATLAB 2017a, но я застрял. Прежде всего, когда я интегрирую с помощью следующего скрипта, я получаю правильный результат. Итак, скрипт работает для x0, который зависит от t.

function E=sol(n,k)
x0 = @(t)  t^(2);
j = 0;
E = zeros(n,1);
 while j < n+1 ;
    K = matlabFunction(subs(po(j,k))) ; 
    eval(sprintf('x%d = integral(K,0,1);',j+1)) ;
    E(j+1,1) = subs(sprintf('x%d',j+1))
    j = j+1;
 end
end

Где функция po(j,k) выглядит следующим образом:

function A_j = po(j,k)          % Adomian polynomials
 if j >0
  x =  sym('x',[1 j]);
    syms p;                            % Assinging a symbolic variable for p
    syms x0;
    S = x0+ sum(p.^(1:j) .* x) ;     % Sum of p*x up to order j
    Q =f(S,k);                        % Taking the k-th power of S, i.e. 
    A_nc = diff(Q,p,j)/factorial(j);  % Taking the j-th order derivative 
    A_j = subs(A_nc,p,0) ;            % Filling in p=0
 else
    syms x0;
    S = x0; 
    A_j =f(S,k);                      % Taking the k-th power of S,
  end
 end 

А где f(x,k),

function F = f(x,k) % Nonlinear function of k power
 F = x^k ;
end

Теперь, когда я вызываю sol(n,k), он работает. Но когда я пытаюсь изменить свою функцию x0 в sol(n,k) в постоянной функции, например,

function E=solcon(n,k)
x0 = @(t) 2.*ones(size(t));
j = 0;
E = zeros(n,1);
 while j < n+1 ;
    K = matlabFunction(subs(po(j,k))) ; 
    eval(sprintf('x%d = integral(K,0,1);',j+1)) ;
    E(j+1,1) = subs(sprintf('x%d',j+1))
    j = j+1;
 end
end

Это не работает. Как видите, я добавил *ones(size(t)); только для того, чтобы сделать его функцией t. Но, к сожалению, он все еще не работает, когда я звоню,

K = matlabFunction(subs(po(j,k))) ;

Я получил,

@()4.0

А то при звонке получаю ошибку

eval(sprintf('x%d = integral(K,0,1);',j+1)) 

Может ли кто-нибудь помочь мне интегрировать константу?

Ошибка, которую я получаю, когда звоню solcon(10,2),

Error using symengine>@()4.0
Too many input arguments.

Error in integralCalc/iterateScalarValued (line 314)
            fx = FUN(t);

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);

Error in solcon1 (line 7)
eval(sprintf('x%d = integral(K,0,1);',j+1)) ;

РЕДАКТИРОВАТЬ 2 Я использовал следующий скрипт,

function E=solcon(n,k)
x0 = @(t) 2.*ones(size(t));
j = 0;
E = zeros(n,1);
 while j < n+1 ;
    K = matlabFunction(subs(po(j,k))) ; 
    fstr= func2str(K)
    if fstr(3) == ')';
       x{j+1} = K*(1-0)
    else x{j+1} = integral(K,0,1)
    end
 E(j+1,1) = subs(x{j+1},1);
 j = j+1
 end
end

Но возникает следующая ошибка,

Undefined operator '*' for input arguments of type 'function_handle'.
Error in solcone1 (line 9)
x{j+1} = K*(1-0);

person Airapet    schedule 08.06.2018    source источник
comment
Это не решит вашу проблему, но определенно улучшит ваше программирование и улучшит будущие головные боли, если вы просто полностью избежите использования eval. Используйте x{jj+1}   -  person Ander Biguri    schedule 08.06.2018


Ответы (1)


Я собираюсь проигнорировать ужасный выбор использования eval, особенно когда вы можете сделать

x{j+1} = integral(K,0,1);

Подробнее о том, почему динамические переменные и eval ужасны


Твоя проблема в том, что matlabFunction умница. Когда он обнаруживает, что ваша функция не имеет никакой зависимости от x, он предоставляет вам функцию с пустыми входными аргументами @()4.0. Как видите, integral это не нравится.

Способ решения проблемы заключается в обнаружении этого перед вызовом integral. Вы можете проверить, есть ли у него входные аргументы, а если нет, то вычислить интеграл "вручную"

 ...
 while j < n+1 ;

    K = matlabFunction(subs(po(j,k))) ; 
    fstr=func2str(K);
    if fstr(3)==')'
         x{j+1}=K()*(1-0); % evaluate the integral yourself
    else
         x{j+1} = integral(K,0,1);
    end
    E(j+1,1) = subs(x{j+1});
    j = j+1;
 end
...

Проблема значительно сложнее, чем я думал. Либо перепишите все это, либо используйте eval:

 ...
 while j < n+1 ;

    K = matlabFunction(subs(po(j,k))) ; 
    fstr=func2str(K);
    if j==0
          eval(sprintf('x%d = K()*(1-0);;',j+1)) ;
    else
          eval(sprintf('x%d = integral(K,0,1);',j+1)) ;
    end
     E(j+1,1) = subs(sprintf('x%d',j+1));
    j = j+1;
 end
...
person Ander Biguri    schedule 08.06.2018
comment
Я не могу использовать эти скобки в x{j+1}, если не укажу массив ячеек. Но мой x не определен таким образом в po. - person Airapet; 08.06.2018
comment
@Airapet Массив ячеек - это массив, который содержит все, что вы хотите. Каким образом указана ваша функция, чтобы она не соответствовала тому, что вы хотите определить? syms x; f=x.^2; g=@(x)(x^2); a{1}=f; a{2}=g; работает нормально - person Ander Biguri; 08.06.2018
comment
Когда я вызываю функцию сейчас, я получаю сообщение об ошибке, которое я разместил в разделе EDIT 2. - person Airapet; 08.06.2018
comment
@Airapet Это потому, что ты немного плохо копируешь: P. Это K() не K - person Ander Biguri; 08.06.2018
comment
Именно то, что я сказал в комментарии.......x{j+1}=K()*(1-0); НЕ x{j+1}=K*(1-0);. K — это функция, ее нужно оценить, даже если она не имеет входных данных. - person Ander Biguri; 08.06.2018
comment
Давайте продолжим обсуждение в чате. - person Airapet; 08.06.2018
comment
Я собираюсь проигнорировать ужасный выбор использования eval... но прочитайте эту ссылку, потому что я не могу ее вообще игнорировать. РЖУ НЕ МОГУ! - person Cris Luengo; 08.06.2018
comment
@Cris, это было то или иное переписывание всего, что я должен был сделать :p - person Ander Biguri; 09.06.2018