В этом примере показано, как решить полиномиальные уравнения и системы уравнений, и работать с результатами с помощью Symbolic Math Toolbox™.
Гауссовы квадратурные правила аппроксимируют интеграл суммами . Здесь, и параметры метода, в зависимости от но не на . Они следуют из выбора функции веса , можно следующим образом. Сопоставленный к функции веса семейство ортогональных полиномов. Корни полиномов являются точками оценки . Наконец, веса убеждены условием, что метод правилен для полиномов маленькой степени. Рассмотрите функцию веса на интервале . Этот случай известен как квадратуру Лагерра Гаусса.
syms t
n = 4;
w(t) = exp(-t);
Примите, что вы знаете первое члены семейства ортогональных полиномов. В случае квадратурного правила, рассмотренного здесь, они оказываются полиномами Лагерра.
F = laguerreL(0:n-1, t)
F =
Позвольте L
будьте полином Св., коэффициенты которого должны все еще быть определены.
X = sym('X', [1, n+1])
X =
L = poly2sym(X, t)
L =
Представляйте отношения ортогональности между полиномами Лагерра F
и L
в системе уравнений sys
.
sys = [int(F.*L.*w(t), t, 0, inf) == 0]
sys =
Добавьте условие, что полином имеет норму 1.
sys = [sys, int(L^2.*w(t), 0, inf) == 1]
sys =
Решите для коэффициентов L
.
S = solve(sys, X)
S = struct with fields:
X1: [2x1 sym]
X2: [2x1 sym]
X3: [2x1 sym]
X4: [2x1 sym]
X5: [2x1 sym]
solve
возвращает эти два решения в массиве структур. Отобразите решения.
structfun(@display, S)
ans =
ans =
ans =
ans =
ans =
Сделайте решение уникальным путем наложения дополнительного условия что первый коэффициент быть положительными:
sys = [sys, X(1)>0]; S = solve(sys, X)
S = struct with fields:
X1: [1x1 sym]
X2: [1x1 sym]
X3: [1x1 sym]
X4: [1x1 sym]
X5: [1x1 sym]
Замените решением в L
.
L = subs(L, S)
L =
Как ожидалось этот полином является |n|th полиномом Лагерра:
laguerreL(n, t)
ans =
Точки оценки корни полиномиального L
. Решите L
для точек оценки. Корни описываются в терминах root
функция.
x = solve(L)
x =
Форма решений может предположить, что ничто не было достигнуто, но различные операции доступны на них. Вычислите приближения с плавающей точкой с помощью vpa
:
vpa(x)
ans =
Могут произойти некоторые побочные мнимые части. Докажите символически, что корни являются вещественными числами:
isAlways(in(x, 'real'))
ans = 4x1 logical array
1
1
1
1
Для полиномов степени, меньше чем или равной 4, можно использовать MaxDegree
получить решения в терминах вложенных радикалов вместо этого в терминах root
. Однако последующие операции на результатах этой формы были бы медленными.
xradical = solve(L, 'MaxDegree', 4)
xradical =
Веса даны условием это для полиномов степени меньше, чем , квадратурное правило должно привести к точным результатам. Достаточно, если это содержит для базиса векторного пространства этих полиномов. Это условие приводит к системе четырех уравнений в четырех переменных.
y = sym('y', [n, 1]); sys = sym(zeros(n)); for k=0:n-1 sys(k+1) = sum(y.*(x.^k)) == int(t^k * w(t), t, 0, inf); end sys
sys =
Решите систему и численно и символически. Решение является желаемым вектором из весов .
[a1, a2, a3, a4] = vpasolve(sys, y)
a1 =
a2 =
a3 =
a4 =
[alpha1, alpha2, alpha3, alpha4] = solve(sys, y)
alpha1 =
alpha2 =
alpha3 =
alpha4 =
В качестве альтернативы можно также получить решение как структуру путем предоставления только одного выходного аргумента.
S = solve(sys, y)
S = struct with fields:
y1: [1x1 sym]
y2: [1x1 sym]
y3: [1x1 sym]
y4: [1x1 sym]
structfun(@double, S)
ans = 4×1
0.6032
0.3574
0.0389
0.0005
Преобразуйте структуру S
к символьному массиву:
Scell = struct2cell(S); alpha = transpose([Scell{:}])
alpha =
Символьное решение выглядит сложным. Упростите его и преобразуйте его в вектор с плавающей точкой:
alpha = simplify(alpha)
alpha =
vpa(alpha)
ans =
Увеличьте удобочитаемость, заменив случаи корней x
в alpha
сокращениями:
subs(alpha, x, sym('R', [4, 1]))
ans =
Суммируйте веса, чтобы показать, что их сумма равняется 1:
simplify(sum(alpha))
ans =
Различный метод, чтобы получить веса квадратурного правила должен вычислить их использующий формулу . Сделайте это для . Это приводит к тому же результату как другой метод:
int(w(t) * prod((t - x(2:4)) ./ (x(1) - x(2:4))), t, 0, inf)
ans =
Квадратурное правило приводит к точным результатам даже для всех полиномов степени, меньше чем или равной , но не для .
simplify(sum(alpha.*(x.^(2*n-1))) -int(t^(2*n-1)*w(t), t, 0, inf))
ans =
simplify(sum(alpha.*(x.^(2*n))) -int(t^(2*n)*w(t), t, 0, inf))
ans =
Примените квадратурное правило к косинусу и сравните с точным результатом:
vpa(sum(alpha.*(cos(x))))
ans =
int(cos(t)*w(t), t, 0, inf)
ans =
Для степеней косинуса ошибка колеблется между четными и нечетными степенями:
errors = zeros(1, 20); for k=1:20 errors(k) = double(sum(alpha.*(cos(x).^k)) -int(cos(t)^k*w(t), t, 0, inf)); end plot(real(errors))