Пример #1
0
 public override RealVector ebeDivide(RealVector v) /*Todo: Supposed to be ArrayRealVector */
 {
     if (v is ArrayRealVector)
     {
         double[] vData = ((ArrayRealVector)v).data;
         int      dim   = vData.Length;
         checkVectorDimensions(dim);
         ArrayRealVector result     = new ArrayRealVector(dim);
         double[]        resultData = result.data;
         for (int i = 0; i < dim; i++)
         {
             resultData[i] = data[i] / vData[i];
         }
         return(result);
     }
     else
     {
         checkVectorDimensions(v);
         double[] @out = data.Clone() as double[];
         for (int i = 0; i < data.Length; i++)
         {
             @out[i] /= v.getEntry(i);
         }
         return(new ArrayRealVector(@out, false));
     }
 }
Пример #2
0
            /**
             * Solves the linear equation A &times; X = B for symmetric matrices A.
             * <p>
             * This method only finds exact linear solutions, i.e. solutions for
             * which ||A &times; X - B|| is exactly 0.
             * </p>
             *
             * @param b Right-hand side of the equation A &times; X = B.
             * @return a Vector X that minimizes the two norm of A &times; X - B.
             *
             * @throws DimensionMismatchException if the matrices dimensions do not match.
             * @throws SingularMatrixException if the decomposed matrix is singular.
             */
            public RealVector solve(RealVector b)
            {
                if (!isNonSingular())
                {
                    throw new Exception("SingularMatrixException");
                }

                int m = realEigenvalues.Length;

                if (b.getDimension() != m)
                {
                    throw new Exception("DimensionMismatchException");
                }

                double[] bp = new double[m];
                for (int i = 0; i < m; ++i)
                {
                    ArrayRealVector v     = eigenvectors[i];
                    double[]        vData = v.getDataRef();
                    double          s     = v.dotProduct(b) / realEigenvalues[i];
                    for (int j = 0; j < m; ++j)
                    {
                        bp[j] += s * vData[j];
                    }
                }

                return(new ArrayRealVector(bp, false));
            }
Пример #3
0
 public override RealVector subtract(RealVector v) /*Todo: Supposed to return ArrayRealVector */
 {
     if (v is ArrayRealVector)
     {
         double[] vData = ((ArrayRealVector)v).data;
         int      dim   = vData.Length;
         checkVectorDimensions(dim);
         ArrayRealVector result     = new ArrayRealVector(dim);
         double[]        resultData = result.data;
         for (int i = 0; i < dim; i++)
         {
             resultData[i] = data[i] - vData[i];
         }
         return(result);
     }
     else
     {
         checkVectorDimensions(v);
         double[] @out = data.Clone() as double[];
         var      it   = v.iterator();
         while (it.MoveNext())
         {
             Entry e = it.Current;
             @out[e.getIndex()] -= e.getValue();
         }
         return(new ArrayRealVector(@out, false));
     }
 }
Пример #4
0
        /**
         * Construct a vector by appending one vector to another vector.
         * @param v1 First vector (will be put in front of the new vector).
         * @param v2 Second vector (will be put at back of the new vector).
         */
        public ArrayRealVector(double[] v1, ArrayRealVector v2)
        {
            int l1 = v1.Length;
            int l2 = v2.getDimension();

            data = new double[l1 + l2];
            Array.Copy(v1, 0, data, 0, l1);
            Array.Copy(v2.data, 0, data, l1, l2);
        }
Пример #5
0
        /**
         * Construct a vector by appending one vector to another vector.
         * @param v1 First vector (will be put in front of the new vector).
         * @param v2 Second vector (will be put at back of the new vector).
         */
        public ArrayRealVector(RealVector v1, ArrayRealVector v2)
        {
            int l1 = v1.getDimension();
            int l2 = v2.data.Length;

            data = new double[l1 + l2];
            for (int i = 0; i < l1; ++i)
            {
                data[i] = v1.getEntry(i);
            }
            Array.Copy(v2.data, 0, data, l1, l2);
        }
Пример #6
0
        /**
         * Construct a vector by appending one vector to another vector.
         * @param v1 First vector (will be put in front of the new vector).
         * @param v2 Second vector (will be put at back of the new vector).
         */
        public ArrayRealVector(ArrayRealVector v1, RealVector v2)
        {
            int l1 = v1.data.Length;
            int l2 = v2.getDimension();

            data = new double[l1 + l2];
            Array.Copy(v1.data, 0, data, 0, l1);
            for (int i = 0; i < l2; ++i)
            {
                data[l1 + i] = v2.getEntry(i);
            }
        }
Пример #7
0
        public override RealVector getSubVector(int index, int n)
        {
            if (n < 0)
            {
                throw new Exception("NotPositiveException");
            }
            ArrayRealVector @out = new ArrayRealVector(n);

            try {
                Array.Copy(data, index, @out.data, 0, n);
            } catch (IndexOutOfRangeException e) {
                checkIndex(index);
                checkIndex(index + n - 1);
            }
            return(@out);
        }
Пример #8
0
            /** {@inheritDoc} */
            public RealMatrix solve(RealMatrix b)
            {
                if (!isNonSingular())
                {
                    throw new Exception("SingularMatrixException");
                }

                int m = realEigenvalues.Length;

                if (b.getRowDimension() != m)
                {
                    throw new Exception("DimensionMismatchException");
                }

                int nColB = b.getColumnDimension();

                double[][] bp     = Java.CreateArray <double[][]>(m, nColB);// new double[m][nColB];
                double[]   tmpCol = new double[m];
                for (int k = 0; k < nColB; ++k)
                {
                    for (int i = 0; i < m; ++i)
                    {
                        tmpCol[i] = b.getEntry(i, k);
                        bp[i][k]  = 0;
                    }
                    for (int i = 0; i < m; ++i)
                    {
                        ArrayRealVector v     = eigenvectors[i];
                        double[]        vData = v.getDataRef();
                        double          s     = 0;
                        for (int j = 0; j < m; ++j)
                        {
                            s += v.getEntry(j) * tmpCol[j];
                        }
                        s /= realEigenvalues[i];
                        for (int j = 0; j < m; ++j)
                        {
                            bp[j][k] += s * vData[j];
                        }
                    }
                }

                return(new Array2DRowRealMatrix(bp, false));
            }
Пример #9
0
        /**
         * Find eigenvectors from a matrix transformed to Schur form.
         *
         * @param schur the schur transformation of the matrix
         * @throws MathArithmeticException if the Schur form has a norm of zero
         */
        private void findEigenVectorsFromSchur(SchurTransformer schur)
        {
            double[][] matrixT = schur.getT().getData();
            double[][] matrixP = schur.getP().getData();

            int n = matrixT.Length;

            // compute matrix norm
            double norm = 0.0;

            for (int i = 0; i < n; i++)
            {
                for (int j = Math.Max(i - 1, 0); j < n; j++)
                {
                    norm += Math.Abs(matrixT[i][j]);
                }
            }

            // we can not handle a matrix with zero norm
            if (Precision.equals(norm, 0.0, EPSILON))
            {
                throw new Exception("MathArithmeticException");
            }

            // Backsubstitute to find vectors of upper triangular form

            double r = 0.0;
            double s = 0.0;
            double z = 0.0;

            for (int idx = n - 1; idx >= 0; idx--)
            {
                double p = realEigenvalues[idx];
                double q = imagEigenvalues[idx];

                if (Precision.equals(q, 0.0))
                {
                    // Real vector
                    int l = idx;
                    matrixT[idx][idx] = 1.0;
                    for (int i = idx - 1; i >= 0; i--)
                    {
                        double w = matrixT[i][i] - p;
                        r = 0.0;
                        for (int j = l; j <= idx; j++)
                        {
                            r += matrixT[i][j] * matrixT[j][idx];
                        }
                        if (Precision.compareTo(imagEigenvalues[i], 0.0, EPSILON) < 0)
                        {
                            z = w;
                            s = r;
                        }
                        else
                        {
                            l = i;
                            if (Precision.equals(imagEigenvalues[i], 0.0))
                            {
                                if (w != 0.0)
                                {
                                    matrixT[i][idx] = -r / w;
                                }
                                else
                                {
                                    matrixT[i][idx] = -r / (Precision.EPSILON * norm);
                                }
                            }
                            else
                            {
                                // Solve real equations
                                double x = matrixT[i][i + 1];
                                double y = matrixT[i + 1][i];
                                q = (realEigenvalues[i] - p) * (realEigenvalues[i] - p) +
                                    imagEigenvalues[i] * imagEigenvalues[i];
                                double t = (x * s - z * r) / q;
                                matrixT[i][idx] = t;
                                if (Math.Abs(x) > Math.Abs(z))
                                {
                                    matrixT[i + 1][idx] = (-r - w * t) / x;
                                }
                                else
                                {
                                    matrixT[i + 1][idx] = (-s - y * t) / z;
                                }
                            }

                            // Overflow control
                            double tx = Math.Abs(matrixT[i][idx]);
                            if ((Precision.EPSILON * tx) * tx > 1)
                            {
                                for (int j = i; j <= idx; j++)
                                {
                                    matrixT[j][idx] /= tx;
                                }
                            }
                        }
                    }
                }
                else if (q < 0.0)
                {
                    // Complex vector
                    int l = idx - 1;

                    // Last vector component imaginary so matrix is triangular
                    if (Math.Abs(matrixT[idx][idx - 1]) > Math.Abs(matrixT[idx - 1][idx]))
                    {
                        matrixT[idx - 1][idx - 1] = q / matrixT[idx][idx - 1];
                        matrixT[idx - 1][idx]     = -(matrixT[idx][idx] - p) / matrixT[idx][idx - 1];
                    }
                    else
                    {
                        Complex result = cdiv(0.0, -matrixT[idx - 1][idx],
                                              matrixT[idx - 1][idx - 1] - p, q);
                        matrixT[idx - 1][idx - 1] = result.getReal();
                        matrixT[idx - 1][idx]     = result.getImaginary();
                    }

                    matrixT[idx][idx - 1] = 0.0;
                    matrixT[idx][idx]     = 1.0;

                    for (int i = idx - 2; i >= 0; i--)
                    {
                        double ra = 0.0;
                        double sa = 0.0;
                        for (int j = l; j <= idx; j++)
                        {
                            ra += matrixT[i][j] * matrixT[j][idx - 1];
                            sa += matrixT[i][j] * matrixT[j][idx];
                        }
                        double w = matrixT[i][i] - p;

                        if (Precision.compareTo(imagEigenvalues[i], 0.0, EPSILON) < 0)
                        {
                            z = w;
                            r = ra;
                            s = sa;
                        }
                        else
                        {
                            l = i;
                            if (Precision.equals(imagEigenvalues[i], 0.0))
                            {
                                Complex c = cdiv(-ra, -sa, w, q);
                                matrixT[i][idx - 1] = c.getReal();
                                matrixT[i][idx]     = c.getImaginary();
                            }
                            else
                            {
                                // Solve complex equations
                                double x  = matrixT[i][i + 1];
                                double y  = matrixT[i + 1][i];
                                double vr = (realEigenvalues[i] - p) * (realEigenvalues[i] - p) +
                                            imagEigenvalues[i] * imagEigenvalues[i] - q * q;
                                double vi = (realEigenvalues[i] - p) * 2.0 * q;
                                if (Precision.equals(vr, 0.0) && Precision.equals(vi, 0.0))
                                {
                                    vr = Precision.EPSILON * norm *
                                         (Math.Abs(w) + Math.Abs(q) + Math.Abs(x) +
                                          Math.Abs(y) + Math.Abs(z));
                                }
                                Complex c = cdiv(x * r - z * ra + q * sa,
                                                 x * s - z * sa - q * ra, vr, vi);
                                matrixT[i][idx - 1] = c.getReal();
                                matrixT[i][idx]     = c.getImaginary();

                                if (Math.Abs(x) > (Math.Abs(z) + Math.Abs(q)))
                                {
                                    matrixT[i + 1][idx - 1] = (-ra - w * matrixT[i][idx - 1] +
                                                               q * matrixT[i][idx]) / x;
                                    matrixT[i + 1][idx] = (-sa - w * matrixT[i][idx] -
                                                           q * matrixT[i][idx - 1]) / x;
                                }
                                else
                                {
                                    Complex c2 = cdiv(-r - y * matrixT[i][idx - 1],
                                                      -s - y * matrixT[i][idx], z, q);
                                    matrixT[i + 1][idx - 1] = c2.getReal();
                                    matrixT[i + 1][idx]     = c2.getImaginary();
                                }
                            }

                            // Overflow control
                            double t = Math.Max(Math.Abs(matrixT[i][idx - 1]),
                                                Math.Abs(matrixT[i][idx]));
                            if ((Precision.EPSILON * t) * t > 1)
                            {
                                for (int j = i; j <= idx; j++)
                                {
                                    matrixT[j][idx - 1] /= t;
                                    matrixT[j][idx]     /= t;
                                }
                            }
                        }
                    }
                }
            }

            // Back transformation to get eigenvectors of original matrix
            for (int j = n - 1; j >= 0; j--)
            {
                for (int i = 0; i <= n - 1; i++)
                {
                    z = 0.0;
                    for (int k = 0; k <= Math.Min(j, n - 1); k++)
                    {
                        z += matrixP[i][k] * matrixT[k][j];
                    }
                    matrixP[i][j] = z;
                }
            }

            eigenvectors = new ArrayRealVector[n];
            double[] tmp = new double[n];
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    tmp[j] = matrixP[j][i];
                }
                eigenvectors[i] = new ArrayRealVector(tmp);
            }
        }
Пример #10
0
        /**
         * Find eigenvalues and eigenvectors (Dubrulle et al., 1971)
         *
         * @param householderMatrix Householder matrix of the transformation
         * to tridiagonal form.
         */
        private void findEigenVectors(double[][] householderMatrix)
        {
            double[][] z = householderMatrix.Clone() as double[][];
            int        n = main.Length;

            realEigenvalues = new double[n];
            imagEigenvalues = new double[n];
            double[] e = new double[n];
            for (int i = 0; i < n - 1; i++)
            {
                realEigenvalues[i] = main[i];
                e[i] = secondary[i];
            }
            realEigenvalues[n - 1] = main[n - 1];
            e[n - 1] = 0;

            // Determine the largest main and secondary value in absolute term.
            double maxAbsoluteValue = 0;

            for (int i = 0; i < n; i++)
            {
                if (Math.Abs(realEigenvalues[i]) > maxAbsoluteValue)
                {
                    maxAbsoluteValue = Math.Abs(realEigenvalues[i]);
                }
                if (Math.Abs(e[i]) > maxAbsoluteValue)
                {
                    maxAbsoluteValue = Math.Abs(e[i]);
                }
            }
            // Make null any main and secondary value too small to be significant
            if (maxAbsoluteValue != 0)
            {
                for (int i = 0; i < n; i++)
                {
                    if (Math.Abs(realEigenvalues[i]) <= Precision.EPSILON * maxAbsoluteValue)
                    {
                        realEigenvalues[i] = 0;
                    }
                    if (Math.Abs(e[i]) <= Precision.EPSILON * maxAbsoluteValue)
                    {
                        e[i] = 0;
                    }
                }
            }

            for (int j = 0; j < n; j++)
            {
                int its = 0;
                int m;
                do
                {
                    for (m = j; m < n - 1; m++)
                    {
                        double delta = Math.Abs(realEigenvalues[m]) +
                                       Math.Abs(realEigenvalues[m + 1]);
                        if (Math.Abs(e[m]) + delta == delta)
                        {
                            break;
                        }
                    }
                    if (m != j)
                    {
                        if (its == maxIter)
                        {
                            throw new Exception("MaxCountExceededException");
                        }
                        its++;
                        double q = (realEigenvalues[j + 1] - realEigenvalues[j]) / (2 * e[j]);
                        double t = Math.Sqrt(1 + q * q);
                        if (q < 0.0)
                        {
                            q = realEigenvalues[m] - realEigenvalues[j] + e[j] / (q - t);
                        }
                        else
                        {
                            q = realEigenvalues[m] - realEigenvalues[j] + e[j] / (q + t);
                        }
                        double u = 0.0;
                        double s = 1.0;
                        double c = 1.0;
                        int    i;
                        for (i = m - 1; i >= j; i--)
                        {
                            double p = s * e[i];
                            double h = c * e[i];
                            if (Math.Abs(p) >= Math.Abs(q))
                            {
                                c        = q / p;
                                t        = Math.Sqrt(c * c + 1.0);
                                e[i + 1] = p * t;
                                s        = 1.0 / t;
                                c       *= s;
                            }
                            else
                            {
                                s        = p / q;
                                t        = Math.Sqrt(s * s + 1.0);
                                e[i + 1] = q * t;
                                c        = 1.0 / t;
                                s       *= c;
                            }
                            if (e[i + 1] == 0.0)
                            {
                                realEigenvalues[i + 1] -= u;
                                e[m] = 0.0;
                                break;
                            }
                            q = realEigenvalues[i + 1] - u;
                            t = (realEigenvalues[i] - q) * s + 2.0 * c * h;
                            u = s * t;
                            realEigenvalues[i + 1] = q + u;
                            q = c * t - h;
                            for (int ia = 0; ia < n; ia++)
                            {
                                p            = z[ia][i + 1];
                                z[ia][i + 1] = s * z[ia][i] + c * p;
                                z[ia][i]     = c * z[ia][i] - s * p;
                            }
                        }
                        if (t == 0.0 && i >= j)
                        {
                            continue;
                        }
                        realEigenvalues[j] -= u;
                        e[j] = q;
                        e[m] = 0.0;
                    }
                } while (m != j);
            }

            //Sort the eigen values (and vectors) in increase order
            for (int i = 0; i < n; i++)
            {
                int    k = i;
                double p = realEigenvalues[i];
                for (int j = i + 1; j < n; j++)
                {
                    if (realEigenvalues[j] > p)
                    {
                        k = j;
                        p = realEigenvalues[j];
                    }
                }
                if (k != i)
                {
                    realEigenvalues[k] = realEigenvalues[i];
                    realEigenvalues[i] = p;
                    for (int j = 0; j < n; j++)
                    {
                        p       = z[j][i];
                        z[j][i] = z[j][k];
                        z[j][k] = p;
                    }
                }
            }

            // Determine the largest eigen value in absolute term.
            maxAbsoluteValue = 0;
            for (int i = 0; i < n; i++)
            {
                if (Math.Abs(realEigenvalues[i]) > maxAbsoluteValue)
                {
                    maxAbsoluteValue = Math.Abs(realEigenvalues[i]);
                }
            }
            // Make null any eigen value too small to be significant
            if (maxAbsoluteValue != 0.0)
            {
                for (int i = 0; i < n; i++)
                {
                    if (Math.Abs(realEigenvalues[i]) < Precision.EPSILON * maxAbsoluteValue)
                    {
                        realEigenvalues[i] = 0;
                    }
                }
            }
            eigenvectors = new ArrayRealVector[n];
            double[] tmp = new double[n];
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    tmp[j] = z[j][i];
                }
                eigenvectors[i] = new ArrayRealVector(tmp);
            }
        }
Пример #11
0
 /**
  * Construct a vector by appending a vector to this vector.
  *
  * @param v Vector to append to this one.
  * @return a new vector.
  */
 public ArrayRealVector append(ArrayRealVector v)
 {
     return(new ArrayRealVector(this, v));
 }
Пример #12
0
 /**
  * Construct a vector by appending one vector to another vector.
  * @param v1 First vector (will be put in front of the new vector).
  * @param v2 Second vector (will be put at back of the new vector).
  */
 public ArrayRealVector(ArrayRealVector v1, ArrayRealVector v2)
 {
     data = new double[v1.data.Length + v2.data.Length];
     Array.Copy(v1.data, 0, data, 0, v1.data.Length);
     Array.Copy(v2.data, 0, data, v1.data.Length, v2.data.Length);
 }
Пример #13
0
 /**
  * Construct a vector from another vector.
  *
  * @param v Vector to copy.
  * @param deep If {@code true} perform a deep copy, otherwise perform a
  * shallow copy.
  */
 public ArrayRealVector(ArrayRealVector v, bool deep)
 {
     data = (deep ? v.data.Clone() : v.data) as double[];
 }
Пример #14
0
 /**
  * Construct a vector from another vector, using a deep copy.
  *
  * @param v Vector to copy.
  * @throws NullArgumentException if {@code v} is {@code null}.
  */
 public ArrayRealVector(ArrayRealVector v)  : this(v, true)
 {
 }