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

Symbolic Math Toolbox™ предлагает и числовое, и символьное уравнения решатели. Для сравнения числовых и символьных решателей смотрите Select Numeric или 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,765208781492784656172932675903') + 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

Figure contains an axes. The axes contains an object of type functionline.

Использование 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.49336143134641450192887776217')

Потому что '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.49336143134641450192887776217'); 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])

Figure contains an axes. The axes with title System of Multivariate Equations contains 3 objects of type implicitfunctionsurface.

Использование vpasolve для поиска точки пересечения поверхностей. Функция vpasolve возвращает структуру. Для доступа к x-, y-, и 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 используйте случайные начальные точки при последующих запусках. The '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

Figure contains an axes. The axes with title Randomly Found Solutions in Specified Search Range contains 4 objects of type implicitfunctionsurface, scatter.

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

digits(digitsOld)