牛顿';Java中求复数根的s方法
我的Java类中有一个项目,我遇到了麻烦。 该项目基本上是在屏幕上标记坐标,从中生成一个(复数)多项式,然后使用牛顿法使用随机猜测求解多项式,并在屏幕上绘制猜测的路径。 我对图纸、标记等没有任何问题。 但出于某种原因,我的牛顿法算法随机地漏掉了根。有时它没有击中任何一个,有时它错过了一两个。我已经换了好几个小时的东西了,但我真的想不出一个解决办法。 当一个根丢失时,通常我在数组中得到的值要么收敛到无穷大,要么是负无穷大(非常高的数值) 任何帮助都将不胜感激牛顿';Java中求复数根的s方法,java,newtons-method,Java,Newtons Method,我的Java类中有一个项目,我遇到了麻烦。 该项目基本上是在屏幕上标记坐标,从中生成一个(复数)多项式,然后使用牛顿法使用随机猜测求解多项式,并在屏幕上绘制猜测的路径。 我对图纸、标记等没有任何问题。 但出于某种原因,我的牛顿法算法随机地漏掉了根。有时它没有击中任何一个,有时它错过了一两个。我已经换了好几个小时的东西了,但我真的想不出一个解决办法。 当一个根丢失时,通常我在数组中得到的值要么收敛到无穷大,要么是负无穷大(非常高的数值) 任何帮助都将不胜感激 > // Polynomial
> // Polynomial evaluation method.
public Complex evalPoly(Complex complexArray[], Complex guess) {
Complex result = new Complex(0, 0);
for (int i = 0; i < complexArray.length; i++) {
result = result.gaussMult(guess).addComplex(complexArray[complexArray.length - i - 1]);
}
return result;
}
> // Polynomial differentation method.
public Complex[] diff(Complex[] comp) {
Complex[] result = new Complex[comp.length - 1];
for (int j = 0; j < result.length; j++) {
result[j] = new Complex(0, 0);
}
for (int i = 0; i < result.length - 1; i++) {
result[i].real = comp[i + 1].real * (i + 1);
result[i].imaginary = comp[i + 1].imaginary * (i + 1);
}
return result;
}
> // Method which eliminates some of the things that I don't want to go into the array
public boolean rootCheck2(Complex[] comps, Complex comp) {
double accLim = 0.01;
if (comp.real == Double.NaN)
return false;
if (comp.real == Double.NEGATIVE_INFINITY || comp.real == Double.POSITIVE_INFINITY)
return false;
if (comp.imaginary == Double.NaN)
return false;
if (comp.imaginary == Double.NEGATIVE_INFINITY || comp.imaginary == Double.POSITIVE_INFINITY)
return false;
for (int i = 0; i < comps.length; i++) {
if (Math.abs(comp.real - comps[i].real) < accLim && Math.abs(comp.imaginary - comps[i].imaginary) < accLim)
return false;
}
return true;
}
> // Method which finds (or attempts) to find all of the roots
public Complex[] addUnique2(Complex[] poly, Bitmap bitmapx, Paint paint, Canvas canvasx) {
Complex[] rootsC = new Complex[poly.length - 1];
int iterCount = 0;
int iteLim = 20000;
for (int i = 0; i < rootsC.length; i++) {
rootsC[i] = new Complex(0, 0);
}
while (iterCount < iteLim && MainActivity.a < rootsC.length) {
double guess = -492 + 984 * rand.nextDouble();
double guess2 = -718 + 1436 * rand.nextDouble();
if (rootCheck2(rootsC, findRoot2(poly, new Complex(guess, guess2), bitmapx, paint, canvasx))) {
rootsC[MainActivity.a] = findRoot2(poly, new Complex(guess, guess2), bitmapx, paint, canvasx);
MainActivity.a = MainActivity.a + 1;
}
iterCount = iterCount + 1;
}
return rootsC;
}
> // Method which finds a single root of the complex polynomial.
public Complex findRoot2(Complex[] comp, Complex guess, Bitmap bitmapx, Paint paint, Canvas canvasx) {
int iterCount = 0;
double accLim = 0.001;
int itLim = 20000;
Complex[] diffedComplex = diff(comp);
while (Math.abs(evalPoly(comp, guess).real) >= accLim && Math.abs(evalPoly(comp, guess).imaginary) >= accLim) {
if (iterCount >= itLim) {
return new Complex(Double.NaN, Double.NaN);
}
if (evalPoly(diffedComplex, guess).real == 0 || evalPoly(diffedComplex, guess).imaginary == 0) {
return new Complex(Double.NaN, Double.NaN);
}
iterCount = iterCount + 1;
guess.real = guess.subtractComplex(evalPoly(comp, guess).divideComplex(evalPoly(diffedComplex, guess))).real;
guess.imaginary = guess.subtractComplex(evalPoly(comp, guess).divideComplex(evalPoly(diffedComplex, guess))).imaginary;
drawCircles((float) guess.real, (float) guess.imaginary, paint, canvasx, bitmapx);
}
return guess;
}
> // Drawing method
void drawCircles(float x, float y, Paint paint, Canvas canvasx, Bitmap bitmapx) {
canvasx.drawCircle(x + 492, shiftBackY(y), 5, paint);
coordPlane.setAdjustViewBounds(false);
coordPlane.setImageBitmap(bitmapx);
}
}
//多项式求值方法。
公共综合体evalPoly(综合体综合体阵列[],综合体猜测){
复合物结果=新的复合物(0,0);
对于(int i=0;i//多项式微分法。
公共综合体[]差异(综合体[]复合){
复合物[]结果=新复合物[comp.length-1];
对于(int j=0;j//方法,它消除了一些我不想进入数组的内容
公共布尔rootCheck2(复数[]comp,复数comp){
双accLim=0.01;
if(comp.real==Double.NaN)
返回false;
if(comp.real==Double.NEGATIVE | | comp.real==Double.NEGATIVE |
返回false;
如果(复合虚拟==Double.NaN)
返回false;
if(comp.virtual==Double.NEGATIVE | | comp.virtual==Double.NEGATIVE |
返回false;
对于(int i=0;i//查找(或尝试)所有根的方法
公共复合体[]addUnique2(复合体[]多边形、位图位图位图、油漆、画布画布){
复数[]根SC=新复数[poly.length-1];
int iterCount=0;
int-iteLim=20000;
for(int i=0;i//查找复数多项式的单根的方法。
公共复合findRoot2(复合[]复合、复合猜测、位图位图位图、绘画、画布画布){
int iterCount=0;
双accLim=0.001;
int-itLim=20000;
复数[]差分复数=diff(comp);
while(Math.abs(evalPoly(comp,guess.real)>=accLim&&Math.abs(evalPoly(comp,guess.virtual)>=accLim){
如果(iterCount>=itLim){
返回新复合体(Double.NaN,Double.NaN);
}
if(evalPoly(differencecomplex,guess)。real==0 | | evalPoly(differencecomplex,guess)。virtual==0){
返回新复合体(Double.NaN,Double.NaN);
}
iterCount=iterCount+1;
guess.real=guess.subtractComplex(evalPoly(comp,guess)。divideComplex(evalPoly(differencecomplex,guess))).real;
guess.virginal=guess.subtract复数(evalPoly(comp,guess)。divideComplex(evalPoly(differencecomplex,guess)))。virginal;
画圈((float)guess.real,(float)guess.virtual,绘画,画布,位图);
}
返回猜测;
}
>//绘图方法
空心画圈(浮动x、浮动y、绘制颜料、画布画布画布x、位图位图位图x){
画布x.画圈(x+492,shiftBackY(y),5,绘画);
coordPlane.setAdjustViewBounds(false);
coordPlane.setImageBitmap(位图);
}
}
错误1
台词
guess.real = guess.subtractComplex(evalPoly(comp, guess).divideComplex(evalPoly(diffedComplex, guess))).real;
guess.imaginary = guess.subtractComplex(evalPoly(comp, guess).divideComplex(evalPoly(diffedComplex, guess))).imaginary;
首先引入一个不必要的复杂性,然后引入一个使其偏离牛顿方法的误差。第二行中使用的guess
与第一行中使用的guess
不同,因为实际零件已更改
为什么不像在评估过程中那样,不使用中的复杂作业
guess = guess.subtractComplex(evalPoly(comp, guess).divideComplex(evalPoly(diffedComplex, guess)));
错误2(更新) 在差分多项式的计算中,缺少中的最高阶项
for (int i = 0; i < result.length - 1; i++) {
result[i].real = comp[i + 1].real * (i + 1);
result[i].imaginary = comp[i + 1].imaginary * (i + 1);
使用3*N
点,随机或等距,在该圆上或附近,应增加到达每个根的概率
但是找到所有根的通常方法是使用多项式压缩,也就是说,分离与已经找到的根近似对应的线性因子。然后,使用完整多项式的两个额外牛顿步恢复最大精度
牛顿分形 每个根都有一个吸引域或吸引域,吸引域之间有分形边界。在重建一个类似的情况下使用的 我计算了一个牛顿分形图,它表明对其中两个根的吸引和对另外两个根的忽略是数学的一个特征
R = 1+max(abs(c[0:N-1]))/abs(c[N])