В этом примере показано, как решать полиномиальные уравнения и системы уравнений и работать с результатами с помощью символьных математических Toolbox™.
Правила гауссовой квадратуры аппроксимируют интеграл суммами xi) αi. Здесь и αi являются параметрами метода, в зависимости от n, но не от f. Они следуют из выбора весовой функции w (t) следующим образом. С весовой функцией связано семейство ортогональных многочленов. Корни многочленов являются точками оценки xi. Наконец, веса αi определяются условием, что метод будет правильным для многочленов малой степени. Рассмотрим = exp (-t) интервале [0,∞]. Этот случай известен как квадратура Гаусса-Лагера.
syms t
n = 4;
w(t) = exp(-t);Предположим, что вы знаете первые членов семейства ортогональных многочленов. В случае рассматриваемого здесь квадратурного правила они оказываются многочленами Лагера.
F = laguerreL(0:n-1, t)
F =
Давайте L быть 1-м многочленом, коэффициенты которого ещё предстоит определить.
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 =
Как и ожидалось, этот многочлен является многочленом Лагера:
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 =
Другим способом получения весов квадратурного правила является их вычисление по формуле ∏j≠it-xjxi-xjdt. Сделайте это = 1. Это приводит к тому же результату, что и другой метод:
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))
