Ejemplo n.º 1
0
        /*************************************************************************
        Polynomial root finding.

        This function returns all roots of the polynomial
            P(x) = a0 + a1*x + a2*x^2 + ... + an*x^n
        Both real and complex roots are returned (see below).

        INPUT PARAMETERS:
            A       -   array[N+1], polynomial coefficients:
                        * A[0] is constant term
                        * A[N] is a coefficient of X^N
            N       -   polynomial degree

        OUTPUT PARAMETERS:
            X       -   array of complex roots:
                        * for isolated real root, X[I] is strictly real: IMAGE(X[I])=0
                        * complex roots are always returned in pairs - roots occupy
                          positions I and I+1, with:
                          * X[I+1]=Conj(X[I])
                          * IMAGE(X[I]) > 0
                          * IMAGE(X[I+1]) = -IMAGE(X[I]) < 0
                        * multiple real roots may have non-zero imaginary part due
                          to roundoff errors. There is no reliable way to distinguish
                          real root of multiplicity 2 from two  complex  roots  in
                          the presence of roundoff errors.
            Rep     -   report, additional information, following fields are set:
                        * Rep.MaxErr - max( |P(xi)| )  for  i=0..N-1.  This  field
                          allows to quickly estimate "quality" of the roots  being
                          returned.

        NOTE:   this function uses companion matrix method to find roots. In  case
                internal EVD  solver  fails  do  find  eigenvalues,  exception  is
                generated.

        NOTE:   roots are not "polished" and  no  matrix  balancing  is  performed
                for them.

          -- ALGLIB --
             Copyright 24.02.2014 by Bochkanov Sergey
        *************************************************************************/
        public static void polynomialsolve(double[] a,
            int n,
            ref complex[] x,
            polynomialsolverreport rep)
        {
            double[,] c = new double[0,0];
            double[,] vl = new double[0,0];
            double[,] vr = new double[0,0];
            double[] wr = new double[0];
            double[] wi = new double[0];
            int i = 0;
            int j = 0;
            bool status = new bool();
            int nz = 0;
            int ne = 0;
            complex v = 0;
            complex vv = 0;

            a = (double[])a.Clone();
            x = new complex[0];

            alglib.ap.assert(n>0, "PolynomialSolve: N<=0");
            alglib.ap.assert(alglib.ap.len(a)>=n+1, "PolynomialSolve: Length(A)<N+1");
            alglib.ap.assert(apserv.isfinitevector(a, n+1), "PolynomialSolve: A contains infitite numbers");
            alglib.ap.assert((double)(a[n])!=(double)(0), "PolynomialSolve: A[N]=0");
            
            //
            // Prepare
            //
            x = new complex[n];
            
            //
            // Normalize A:
            // * analytically determine NZ zero roots
            // * quick exit for NZ=N
            // * make residual NE-th degree polynomial monic
            //   (here NE=N-NZ)
            //
            nz = 0;
            while( nz<n && (double)(a[nz])==(double)(0) )
            {
                nz = nz+1;
            }
            ne = n-nz;
            for(i=nz; i<=n; i++)
            {
                a[i-nz] = a[i]/a[n];
            }
            
            //
            // For NZ<N, build companion matrix and find NE non-zero roots
            //
            if( ne>0 )
            {
                c = new double[ne, ne];
                for(i=0; i<=ne-1; i++)
                {
                    for(j=0; j<=ne-1; j++)
                    {
                        c[i,j] = 0;
                    }
                }
                c[0,ne-1] = -a[0];
                for(i=1; i<=ne-1; i++)
                {
                    c[i,i-1] = 1;
                    c[i,ne-1] = -a[i];
                }
                status = evd.rmatrixevd(c, ne, 0, ref wr, ref wi, ref vl, ref vr);
                alglib.ap.assert(status, "PolynomialSolve: inernal error - EVD solver failed");
                for(i=0; i<=ne-1; i++)
                {
                    x[i].x = wr[i];
                    x[i].y = wi[i];
                }
            }
            
            //
            // Remaining NZ zero roots
            //
            for(i=ne; i<=n-1; i++)
            {
                x[i] = 0;
            }
            
            //
            // Rep
            //
            rep.maxerr = 0;
            for(i=0; i<=ne-1; i++)
            {
                v = 0;
                vv = 1;
                for(j=0; j<=ne; j++)
                {
                    v = v+a[j]*vv;
                    vv = vv*x[i];
                }
                rep.maxerr = Math.Max(rep.maxerr, math.abscomplex(v));
            }
        }
Ejemplo n.º 2
0
 public override alglib.apobject make_copy()
 {
     polynomialsolverreport _result = new polynomialsolverreport();
     _result.maxerr = maxerr;
     return _result;
 }