Nadesłany przez Michał Ładanowski, 22 lutego 2011 23:00
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.Pobierz pełne rozwiązanie.
Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.
PolynomialRoots.java:
/** Algorytm szukający miejsc zerowych za pomocą metody Laguerre'a
* Michał Ładanowski (c) 2011
* www.algorytm.org
*/
public class PolynomialRoots {
// współczynniki danego wielomianu P
private Complex[] polynomialCoeff;
public PolynomialRoots(Complex[] polynomialCoeff){
this.polynomialCoeff = polynomialCoeff;
}
// funkcja startująca algorytm
public Complex[] findRoots(){
Complex start = new Complex(0,0);
Complex[] z = new Complex[polynomialCoeff.length -1];
int i = 0;
Complex[] polLess = null;
z[0] = LaguerreMethod(start, polynomialCoeff);
Complex[] tmp = polynomialCoeff;
for(i = 1; i < polynomialCoeff.length -1; i++){
polLess = newPol(z[i-1],tmp);
z[i] = LaguerreMethod(start, polLess);
z[i] = LaguerreMethod(z[i], polynomialCoeff);
tmp = polLess;
}
for(i = 0; i < polynomialCoeff.length -1; i++){
System.out.println(z[i]);
}
return z;
}
// Metoda Laguerre'a
// argumenty:
// start - punkt początkowy
// pol - tablica przechowująca współczynniki wielomianu, którego szukamy mz.
// zmienne:
// fun - P(z)*n
// der - P'(z), secDer - P''(z)
// denominator - mianownik
// zwraca:
// z - miejsce zerowe
private Complex LaguerreMethod(Complex start, Complex[] pol){
Complex z = start;
Complex fun,der,secDer, denominator;
Complex tmp = new Complex(100,0);
// iterujemy tak długo aż różnica między aktualnym a poprzednio
// wyliczonym miejscem zerowym będzie nie mniejsca niż
// zadana precyzja(w tym przypadku 1e-13)
while((horner(z, pol).minus(horner(tmp, pol))).abs() > 1e-13){
tmp = z;
fun = horner(z, pol).times(pol.length-1);
der = horner(z, derivative(pol));
secDer = horner(z, derivative(derivative(pol)));
denominator = ( ( der.times(der).times(((pol.length-1) - 1))
.minus(fun.times(secDer)) ).times((pol.length-1) - 1) ).sqrt();
denominator = der.minus(denominator).abs() > der.plus(denominator).abs()
? der.minus(denominator) : der.plus(denominator);
z = z.minus((fun.divides(denominator)));
}
return z;
}
// wartość wielomianu w z wyliczona za pomocą Hornera
private Complex horner(Complex z, Complex[] coefficients){
Complex P = coefficients[coefficients.length-1];
int k = coefficients.length-1;
while(k >0){
k--;
P = P.times(z).plus(coefficients[k]);
}
return P;
}
// deflacja
public Complex[] newPol(Complex root, Complex[] oldPol){
Complex[] newPol = new Complex[oldPol.length-1];
newPol[oldPol.length -2] = oldPol[oldPol.length -1];
for(int i = oldPol.length - 3; i >= 0; i--){
newPol[i] = oldPol[i+1].plus(newPol[i+1].times(root));
}
return newPol;
}
// funkcja licząca pochodną
public Complex[] derivative(Complex[] pol){
if(pol.length-1 == 0) return new Complex[]{new Complex(0,0)};
Complex[] der = new Complex[pol.length-1];
for(int i = pol.length -2; i >= 0; i-- ){
der[i] = pol[i+1].times(i+1);
}
return der;
}
}

