2014-02-14 4 views
0

Это код:Я использую неправильный численный метод?

f = dsolve('D3y+12*Dy+y = 0 ,y(2) = 1 ,Dy(2) = 1, D2y(2) = -1'); 
feval(symengine, 'numeric::solve',strcat(char(f),'=1'),'t=-4..16','AllRealRoots') 

Если удалить 'AllRealRoots' вариант работает быстро и находит решение, но когда я включаю опцию Matlab не завершается в течение часа. Я использую неправильный численный метод?

ответ

0

Во-первых, прямо из документации numeric::solve:

Если равенствами не является многочленом/нерационально уравнение или множество или список, содержащий такое уравнение, то уравнения и соответствующие необязательные аргументы передается численному решателю числовой :: fsolve.

Так как ваше уравнение f не является многочленом, то вы, вероятно, следует назвать numeric::fsolve напрямую. Однако даже с 'MultiSolutions' он не может вернуть более одного корня из вашего диапазона (возможно, ошибка?) Я использую R2013b). Обойти это можно назвать numeric::realroots, чтобы получить оценки по каждому из районных вещественных корней в вашем диапазоне, а затем решить их по отдельности:

f = dsolve('D3y+12*Dy+y = 0 ,y(2) = 1 ,Dy(2) = 1, D2y(2) = -1'); 
r = feval(symengine, 'numeric::realroots', f==1, 't = -4 .. 16'); 

num_roots = numel(r); 
T = zeros(num_roots,1); % Wrap in sym or vpa for higher precision output 
syms t; 
for i = 1:num_roots 
    bnds = r(i); 
    ri = feval(symengine, '_range', bnds(1), bnds(2)); 
    s = feval(symengine, 'numeric::fsolve', f==1, t==ri); 
    T(i) = feval(symengine, 'rhs', s(1)); 
end 

вектор полученный раствор, T, является двойной точностью (выделить его в качестве sym или vpa вы хотите более высокую точность):

T = 

    -0.663159371123072 
    0.034848320470578 
    0.999047064621451 
    2.000000000000000 
    2.695929753727520 
    3.933983894260340 
    4.405822476913172 
    5.868112290810963 
    6.108685019679461 

вы можете быть в состоянии удалить петлю for, если вы можете выяснить, как чисто пройти на выходе 'numeric::realroots' к 'numeric::fsolve' на одном дыхании (это выполнимо, но может потребовать сотрудничества nverting stuf to strings, если вы не умны).

Другой (возможно, даже быстрее) подход заключается в переходе к использованию цифровой (с плавающей точкой) функции fzero на вторую половину после того, как вы связаны все корни:

f = dsolve('D3y+12*Dy+y = 0 ,y(2) = 1 ,Dy(2) = 1, D2y(2) = -1'); 
r = feval(symengine, 'numeric::realroots', f==1, 't = -4 .. 16'); 

num_roots = numel(r); 
T = zeros(num_roots,1); 
g = matlabFunction(f-1); % Create anonymous function from f 
for i = 1:num_roots 
    bnds = double(r(i)); 
    T(i) = fzero(g,bnds); 
end 

Я проверил, и для вашего проблема здесь и использование допусков по умолчанию, итоговый T находится в нескольких машинах epsilon (eps) решения numeric::fsolve'.

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