Решите уравнения численно

Symbolic Math Toolbox™ предлагает и числовые и символьные решатели уравнения. Для сравнения числовых и символьных решателей смотрите, Выбирают Numeric or Symbolic Solver. Уравнение или система уравнений могут иметь несколько решений. Чтобы найти эти решения численно, используйте функциональный vpasolve. Для полиномиальных уравнений, vpasolve возвращает все решения. Для неполиномиальных уравнений, vpasolve возвращает первое решение, которое это находит. Эти примеры показывают вам, как использовать vpasolve найти решения и полиномиальных и неполиномиальных уравнений, и как получить эти решения произвольной точности.

Найдите все корни полиномиальной функции

Используйте vpasolve найти все решения функции f(x)=6x7-2x6+3x3-8.

syms f(x)
f(x) = 6*x^7-2*x^6+3*x^3-8;
sol = vpasolve(f)
sol = 

(1.0240240759053702941448316563337-0.88080620051762149639205672298326+0.50434058840127584376331806592405i-0.88080620051762149639205672298326-0.50434058840127584376331806592405i-0.22974795226118163963098570610724+0.96774615576744031073999010695171i-0.22974795226118163963098570610724-0.96774615576744031073999010695171i0.7652087814927846556172932675903+0.83187331431049713218367239317121i0.7652087814927846556172932675903-0.83187331431049713218367239317121i)[vpa ('1.0240240759053702941448316563337'); - vpa ('0.88080620051762149639205672298326') + vpa ('0.50434058840127584376331806592405i'); - vpa ('0.88080620051762149639205672298326') - vpa ('0.50434058840127584376331806592405i'); - vpa ('0.22974795226118163963098570610724') + vpa ('0.96774615576744031073999010695171i'); - vpa ('0.22974795226118163963098570610724') - vpa ('0.96774615576744031073999010695171i'); vpa ('0.7652087814927846556172932675903') + vpa ('0.83187331431049713218367239317121i'); vpa ('0.7652087814927846556172932675903') - vpa ('0.83187331431049713218367239317121i')]

vpasolve возвращает семь корней функции, как ожидалось, потому что функция является полиномом степени семь.

Найдите нули неполиномиальной функции Используя поисковые области значений и начальные точки

График функции f(x)=e(x/7)cos(2x) показывает периодические нули, с увеличением наклонов в нулевых точках как x увеличения.

syms x
h = fplot(exp(x/7)*cos(2*x),[-2 25]);
grid on

Используйте vpasolve найти нуль функционального f. Обратите внимание на то, что vpasolve возвращает только одно решение неполиномиального уравнения, даже если существуют несколько решений. На повторных вызовах, vpasolve возвращает тот же результат.

f = exp(x/7)*cos(2*x);
for k = 1:3
  vpasolve(f,x)
end
ans = -7.0685834705770347865409476123789- vpa ('7.0685834705770347865409476123789')
ans = -7.0685834705770347865409476123789- vpa ('7.0685834705770347865409476123789')
ans = -7.0685834705770347865409476123789- vpa ('7.0685834705770347865409476123789')

Чтобы найти несколько решений, установите опцию 'Random' к true. Это делает vpasolve выберите начальные точки случайным образом. Для получения информации об алгоритме, который выбирает случайные начальные точки, см. Алгоритмы на vpasolve страница.

for k = 1:3
  vpasolve(f,x,'Random',true)
end
ans = -226.98006922186256147892598444194- vpa ('226.98006922186256147892598444194')
ans = 98.174770424681038701957605727484vpa ('98.174770424681038701957605727484')
ans = 52.621676947629036744249276669932vpa ('52.621676947629036744249276669932')

Найти нуль близко к x=10, установите начальную точку 10.

vpasolve(f,x,10)
ans = 10.210176124166828025003590995658vpa ('10.210176124166828025003590995658')

Найти нуль близко к x=1000, установите начальную точку 1000.

vpasolve(f,x,1000)
ans = 999.8118620049516981407362567287vpa ('999.8118620049516981407362567287')

Найти нуль в области значений 15x25, установите поисковую область значений на [15 25].

vpasolve(f,x,[15 25])
ans = 21.205750411731104359622842837137vpa ('21.205750411731104359622842837137')

Найти несколько нулей в области значений [15 25], вы не можете вызвать vpasolve неоднократно, потому что это возвращает тот же результат на каждом вызове, как ранее показано. Вместо этого установите поисковую область значений и установите 'Random' к true.

for k = 1:3
  vpasolve(f,x,[15 25],'Random',true)
end
ans = 21.205750411731104359622842837137vpa ('21.205750411731104359622842837137')
ans = 21.205750411731104359622842837137vpa ('21.205750411731104359622842837137')
ans = 16.493361431346414501928877762217vpa ('16.493361431346414501928877762217')

Поскольку 'Random' выбирает начальные точки случайным образом, то же решение может быть найдено на последовательных вызовах.

Найдите все нули в указанном поисковом диапазоне

Создайте функциональный findzeros систематически находить все нули для f в данной поисковой области значений, в заданном ошибочном допуске. Функция запускается с входной области значений поиска и вызывает vpasolve найти нуль. Затем это разделяет поисковую область значений в два вокруг нулевого значения и рекурсивно вызывает себя с новыми поисковыми областями значений как входные параметры, чтобы найти больше нулей.

Функции объясняют раздел разделом здесь.

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

function sol = findzeros(f,range,err)

Если вы не задаете дополнительный аргумент для ошибочного допуска, findzeros наборы err к 0.001.

if nargin < 2
  err = 1e-3;
end

Найдите нуль в поисковой области значений с помощью vpasolve.

sol = vpasolve(f,range);

Если vpasolve не находит нуль, выход.

if(isempty(sol))
  return

Если vpasolve находит нуль, разделите поисковую область значений в две поисковых области значений выше и ниже нуля.

else
  lowLimit = sol-err;
  highLimit = sol+err;

Вызовите findzeros с более низкой поисковой областью значений. Если findzeros возвращает нули, скопируйте значения в массив решения и отсортируйте их.

  temp = findzeros(f,[range(1) lowLimit],1);
  if ~isempty(temp)
    sol = sort([sol temp]);
  end

Вызовите findzeros с более высокой поисковой областью значений. Если findzeros возвращает нули, скопируйте значения в массив решения и отсортируйте их.

  temp = findzeros(f,[highLimit range(2)],1);
  if ~isempty(temp)
    sol = sort([sol temp]);
  end
  return
end
end

Целая функция findzeros следующие. Сохраните эту функцию как findzeros.m в текущей папке.

function sol = findzeros(f,range,err)
if nargin < 3
  err = 1e-3;
end
sol = vpasolve(f,range);
if(isempty(sol))
  return
else
  lowLimit = sol-err;
  highLimit = sol+err;
  temp = findzeros(f,[range(1) lowLimit],1);
  if ~isempty(temp)
    sol = sort([sol temp]);
  end
  temp = findzeros(f,[highLimit range(2)],1);
  if ~isempty(temp)
    sol = sort([sol temp]);
  end
  return
end
end

Вызовите findzeros с поисковой областью значений [15 25] найти все нули в той области значений для f(x) = exp(x/7)*cos(2*x), в ошибочном допуске по умолчанию.

syms f(x)
f(x) = exp(x/7)*cos(2*x);
sol = findzeros(f,[15 25])'
sol = 

(16.49336143134641450192887776221718.06415775814131112116019945385719.63495408493620774039152114549721.20575041173110435962284283713722.77654673852600097885416452877624.347343065320897598085486220416)[vpa ('16.493361431346414501928877762217'); vpa ('18.064157758141311121160199453857'); vpa ('19.634954084936207740391521145497'); vpa ('21.205750411731104359622842837137'); vpa ('22.776546738526000978854164528776'); vpa ('24.347343065320897598085486220416')]

Получите решения произвольной точности

Используйте digits установить точность решений, возвращенных vpasolve. По умолчанию, vpasolve возвращает решения точности 32 значащих цифр.

f = exp(x/7)*cos(2*x);
vpasolve(f)
ans = -7.0685834705770347865409476123789- vpa ('7.0685834705770347865409476123789')

Используйте digits увеличить точность до 64 значащих цифр. При изменении digits, гарантируйте, что вы сохраняете его текущее значение так, чтобы можно было восстановить его.

digitsOld = digits;
digits(64)
vpasolve(f)
ans = -7.068583470577034786540947612378881489443631148593988097193625333- vpa ('7.068583470577034786540947612378881489443631148593988097193625333')

Затем измените точность решений 16 значащих цифр.

digits(16)

Решите многомерные уравнения Используя поисковые области значений

Рассмотрите следующую систему уравнений.

z=10(cos(x)+cos(y))z=x+y2-0.1x2yx+y-2.7=0

График уравнений для 0x2.5 и 0x2.5 показывает, что три поверхности пересекаются в двух точках. Чтобы лучше визуализировать график, используйте view. Чтобы масштабировать значения палитры, используйте caxis.

syms x y z
eqn1 = z == 10*(cos(x) + cos(y));
eqn2 = z == x+y^2-0.1*x^2*y;
eqn3 = x+y-2.7 == 0;
equations = [eqn1 eqn2 eqn3];
fimplicit3(equations)
axis([0 2.5 0 2.5 -20 10])
title('System of Multivariate Equations')
view(69, 28)
caxis([-15 10])

Используйте vpasolve найти точку, где поверхности пересекаются. Функциональный vpasolve возвращает структуру. Получить доступ к xY-, и z- значения решения, индексируйте в структуру.

sol = vpasolve(equations);
[sol.x sol.y sol.z]
ans = (2.3697477224547980.33025227754520212.293354376823228)[vpa ('2.369747722454798'), vpa ('0.3302522775452021'), vpa ('2.293354376823228')]

Чтобы искать область пробела решения, укажите поисковые диапазоны для переменных. Если вы указываете диапазоны 0x1.5 и 1.5y2.5, затем vpasolve функционируйте ищет ограниченную показанную область.

Используйте vpasolve найти решение для этой поисковой области значений. Не использовать поисковую область значений для z, установите третью поисковую область значений на [NaN NaN].

vars = [x y z];
range = [0 1.5; 1.5 2.5; NaN NaN];
sol = vpasolve(equations, vars, range);
[sol.x sol.y sol.z]
ans = (0.91062661725633361.7893733827436663.964101572135625)[vpa ('0.9106266172563336'), vpa ('1.789373382743666'), vpa ('3.964101572135625')]

Чтобы найти несколько решений, установите 'Random' опция к true. Это делает vpasolve используйте случайные начальные точки на последовательных запусках. 'Random' опция может использоваться в сочетании с поисковыми областями значений, чтобы сделать vpasolve используйте случайные начальные точки в поисковой области значений. Поскольку 'Random' выбирает начальные точки случайным образом, то же решение может быть найдено на последовательных вызовах. Вызовите vpasolve неоднократно, чтобы убеждаться вы находите оба решения.

clear sol
range = [0 3; 0 3; NaN NaN];
for k = 1:5
  temp = vpasolve(equations,vars,range,'Random',true);
  sol(k,1) = temp.x;
  sol(k,2) = temp.y;
  sol(k,3) = temp.z;
end
sol
sol = 

(2.3697477224547980.33025227754520212.2933543768232282.3697477224547980.33025227754520212.2933543768232282.3697477224547980.3302522775452022.2933543768232280.91062661725633361.7893733827436663.9641015721356250.91062661725633361.7893733827436663.964101572135625)[vpa ('2.369747722454798'), vpa ('0.3302522775452021'), vpa ('2.293354376823228'); vpa ('2.369747722454798'), vpa ('0.3302522775452021'), vpa ('2.293354376823228'); vpa ('2.369747722454798'), vpa ('0.330252277545202'), vpa ('2.293354376823228'); vpa ('0.9106266172563336'), vpa ('1.789373382743666'), vpa ('3.964101572135625'); vpa ('0.9106266172563336'), vpa ('1.789373382743666'), vpa ('3.964101572135625')]

Постройте уравнения. Наложите решения как график рассеивания точек с желтым X маркеры с помощью scatter3. Чтобы лучше визуализировать график, сделайте две из поверхностей прозрачным использованием alpha. Масштабируйте палитру к значениям графика с помощью caxis, и измените перспективу с помощью view.

vpasolve находит решения на пересечении поверхностей сформированными уравнениями как показано.

clf
ax = axes;
h = fimplicit3(equations);
h(2).FaceAlpha = 0;
h(3).FaceAlpha = 0;
axis([0 2.5 0 2.5 -20 10])
hold on
scatter3(sol(:,1),sol(:,2),sol(:,3),600,'yellow','X','LineWidth',2)
title('Randomly Found Solutions in Specified Search Range')
cz = ax.Children;
caxis([0 20])
view(69,28)
hold off

Наконец, восстановите старое значение digits для дальнейших вычислений.

digits(digitsOld)
Для просмотра документации необходимо авторизоваться на сайте