我必须使用Laguerre的方法编写一段代码,以找到poly的实根和复杂根:
P = X ^ 5-5 * X ^ 4-6 * X ^ 3 + 6 * X ^ 2-3 * X + 1
我毫不怀疑。我在matlab中执行了该算法,但是5个根中有3个是相同的,我认为这是不正确的。
syms X %Declearing x as a variabl
P=X^5-5*X^4-6*X^3+6*X^2-3*X+1; %Equation we interest to solve
n=5; % The eq. order
Pd1 = diff(P,X,1); % first differitial of f
Pd2 = diff(P,X,2); %second differitial of f
err=0.00001; %Answear tollerance
N=100; %Max. # of Iterations
x(1)=1e-3; % Initial Value
for k=1:N
G=double(vpa(subs(Pd1,X,x(k))/subs(P,X,x(k))));
H=G^2 - double(subs(Pd2,X,x(k))) /subs(P,X,x(k));
D1= (G+sqrt((n-1)*(n*H-G^2)));
D2= (G-sqrt((n-1)*(n*H-G^2)));
D = max(D1,D2);
a=n/D;
x(k+1)=x(k)-a
Err(k) = abs(x(k+1)-x(k));
if Err(k) <=err
break
end
end
输出(多项式的根):
x =
0.0010 + 0.0000i 0.1434 + 0.4661i 0.1474 + 0.4345i 0.1474 + 0.4345i 0.1474 + 0.4345i
答案 0 :(得分:1)
您实际看到的是循环中出现的所有值let key = {
"ID": "1",
"NAME": "KEN",
"DEPT1": "CSE",
"DEPT2": "IT",
"DEPT3": "NA",
"EMAIL": "E@T.com"
}
let output = []
const findKey = (searchKey) => {
Object.keys(key).forEach(key1 => {
key[key1] === searchKey ? output.push({
[key1]: key[key1]
}) : null
})
}
findKey("CSE")
console.log(output)
。最后一个x(k)
是此循环的最终结果-根的近似值位于给定的公差阈值内。代码
0.1474 + 0.4345i
结果
syms X %Declaring x as a variable
P = X^5 - 5 * X^4 - 6 * X^3 + 6 * X^2 - 3 * X + 1; %Polynomial
n=5; %Degree of the polynomial
Pd1 = diff(P,X,1); %First derivative of P
Pd2 = diff(P,X,2); %Second derivative of P
err = 0.00001; %Answer tolerance
N = 100; %Maximal number of iterations
x(1) = 0; %Initial value
for k = 1:N
G = double(vpa(subs(Pd1,X,x(k)) / subs(P,X,x(k))));
H = G^2 - double(subs(Pd2,X,x(k))) / subs(P,X,x(k));
D1 = (G + sqrt((n-1) * (n * H-G^2)));
D2 = (G - sqrt((n-1) * (n * H-G^2)));
D = max(D1,D2);
a = n/D;
x(k+1) = x(k) - a;
Err(k) = abs(x(k+1)-x(k));
if Err(k) <=err
fprintf('Initial value %f, result %f%+fi', x(1), real(x(k)), imag(x(k)))
break
end
end
如果要获得其他根,则必须使用其他初始值。例如,一个可以获得
Initial value -2.000000, result -1.649100+0.000000i
这些都是多项式的零。
找到另一个根后,用于计算下一个根的一种方法是:除以相应的线性因子,然后将循环用于生成的新多项式。请注意,这通常不太容易处理,因为舍入误差可能会对结果产生很大的影响。
答案 1 :(得分:0)
使用deconv
函数可以实现除数除法。
其他要点:
max
,它仅对实际输入具有有意义的结果。目的是使a
的两个变体中的较小者,以便必须寻找具有较大绝对值的D
。double
转换没有意义,因为根本没有转换为single
类型。Err
而言。polyval
,polyder
,deconv
。double
类型的机器常数乘以多项式值,在该多项式中所有系数和评估点都被其绝对值代替。测试和中断主要是为了避免被零或接近零的除法。实施所有这些,我得到的日志
0.0010000 0.9970060
x( 1) = 0.143349512707684+0.466072958423667i
x( 2) = 0.164462212064089+0.461399841949893i
x( 3) = 0.164466373475316+0.461405404094130i
root found x=0.164466373475316+0.461405404094130i with value P(x)=-2.22045e-16+9.4369e-16i
1.6447e-01 - 4.6141e-01i 2.1094e-15 - 2.2204e-16i
root found x=0.164466373475316-0.461405404094130i with value P(x)=-2.22045e-16-9.4369e-16i
0.16447 + 0.46141i 3.26094 - 3.44717i
x( 1) = 0.586360702193454+0.016571894375927i
x( 2) = 0.562204173408499+0.000003168181059i
x( 3) = 0.562204925474889+0.000000000000000i
root found x=0.562204925474889+0.000000000000000i with value P(x)=2.22045e-16-1.33554e-17i
0.56220 - 0.00000i -7.72035 + 0.00000i
x( 1) = 3.332994579372812-0.000000000000000i
root found x=3.332994579372812-0.000000000000000i with value P(x)=6.39488e-14-3.52284e-15i
3.3330 + 0.0000i 5.5571 + 0.0000i
x( 1) = -2.224132251798332+0.000000000000000i
root found x=-2.224132251798332+0.000000000000000i with value P(x)=-3.33067e-14+1.6178e-15i
修改后的代码
P = [1, -2, -6, 6, -3, 1];
P0 = P;
deg=length(P)-1; % The eq. degree
err=1e-10; %Answer tolerance
N=10; %Max. # of Iterations
x=1e-3; % Initial Value
for n=deg:-1:1
dP = polyder(P); % first derivative of P
d2P = polyder(dP); %second derivative of P
disp([x, polyval(P,x)]);
for k=1:N
Px = polyval(P,x);
dPx = polyval(dP,x);
d2Px = polyval(d2P,x);
if abs(Px) < 1e-14*polyval(abs(P),abs(x))
break % if value is zero in relative accuracy
end
G = dPx/Px;
H=G^2 - d2Px / Px;
D1= (G+sqrt((n-1)*(n*H-G^2)));
D2= (G-sqrt((n-1)*(n*H-G^2)));
D = D1;
if abs(D2)>abs(D1) D=D2; end % select the larger denominator
a=n/D;
x=x-a;
fprintf('x(%2d) = %.15f%+.15fi\n',k,real(x),imag(x));
if abs(a) < err
break
end
end
y = polyval(P0,x); % check polynomial value of the original polynomial
fprintf('root found x=%.15f%+.15fi with value P(x)=%.6g%+.6gi\n', real(x),imag(x),real(y),imag(y));
[ P,R ] = deconv(P,[1,-x]); % division with remainder
x = conj(x); % shortcut for conjugate pairs and clustered roots
end