Exemplo n.º 1
0
 public static Matrix DMD(Vector diagmat1, Matrix mat, Vector diagmat2)
 {
     if (DMD_selftest)
     #region selftest
     {
         HDebug.ToDo("check");
         DMD_selftest = false;
         Vector td1 = new double[] { 1, 2, 3 };
         Vector td2 = new double[] { 4, 5, 6 };
         Matrix tm  = new double[, ] {
             { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }
         };
         Matrix dmd0 = LinAlg.Diag(td1) * tm * LinAlg.Diag(td2);
         Matrix dmd1 = LinAlg.DMD(td1, tm, td2);
         double err  = (dmd0 - dmd1).HAbsMax();
         HDebug.Assert(err == 0);
     }
     #endregion
     Matrix DMD = mat.Clone();
     for (int c = 0; c < mat.ColSize; c++)
     {
         for (int r = 0; r < mat.RowSize; r++)
         {
             double v0 = mat[c, r];
             double v1 = diagmat1[c] * v0 * diagmat2[r];
             if (v0 == v1)
             {
                 continue;
             }
             DMD[c, r] = v1;
         }
     }
     return(DMD);
 }
Exemplo n.º 2
0
        public static Tuple <MatrixByArr, Vector> Eig(MatrixByArr A)
        {
            if (HDebug.Selftest())
            {
                MatrixByArr tA = new double[, ] {
                    { 1, 2, 3 },
                    { 2, 9, 5 },
                    { 3, 5, 6 }
                };
                MatrixByArr tV = new double[, ] {
                    { -0.8879, 0.3782, 0.2618 },
                    { -0.0539, -0.6508, 0.7573 },
                    { 0.4568, 0.6583, 0.5983 }
                };
                Vector tD = new double[] { -0.4219, 2.7803, 13.6416 };

                Tuple <MatrixByArr, Vector> tVD = Eig(tA);
                Vector tV0 = tVD.Item1.GetColVector(0); double tD0 = tVD.Item2[0];
                Vector tV1 = tVD.Item1.GetColVector(1); double tD1 = tVD.Item2[1];
                Vector tV2 = tVD.Item1.GetColVector(2); double tD2 = tVD.Item2[2];

                HDebug.AssertTolerance(0.00000001, 1 - LinAlg.VtV(tV0, tV0));
                HDebug.AssertTolerance(0.00000001, 1 - LinAlg.VtV(tV1, tV1));
                HDebug.AssertTolerance(0.00000001, 1 - LinAlg.VtV(tV2, tV2));
                MatrixByArr tAA = tVD.Item1 * LinAlg.Diag(tVD.Item2) * tVD.Item1.Tr();
                HDebug.AssertTolerance(0.00000001, tA - tAA);

                //HDebug.AssertTolerance(0.0001, VD.Item1-tV);
                HDebug.AssertTolerance(0.0001, tVD.Item2 - tD);
            }

            HDebug.Assert(A.ColSize == A.RowSize);
            double[] eigval;
            double[,] eigvec;

            #region bool alglib.smatrixevd(double[,] a, int n, int zneeded, bool isupper, out double[] d, out double[,] z)
            /// Finding the eigenvalues and eigenvectors of a symmetric matrix
            ///
            /// The algorithm finds eigen pairs of a symmetric matrix by reducing it to
            /// tridiagonal form and using the QL/QR algorithm.
            ///
            /// Input parameters:
            ///     A       -   symmetric matrix which is given by its upper or lower
            ///                 triangular part.
            ///                 Array whose indexes range within [0..N-1, 0..N-1].
            ///     N       -   size of matrix A.
            ///     ZNeeded -   flag controlling whether the eigenvectors are needed or not.
            ///                 If ZNeeded is equal to:
            ///                  * 0, the eigenvectors are not returned;
            ///                  * 1, the eigenvectors are returned.
            ///     IsUpper -   storage format.
            ///
            /// Output parameters:
            ///     D       -   eigenvalues in ascending order.
            ///                 Array whose index ranges within [0..N-1].
            ///     Z       -   if ZNeeded is equal to:
            ///                  * 0, Z hasn’t changed;
            ///                  * 1, Z contains the eigenvectors.
            ///                 Array whose indexes range within [0..N-1, 0..N-1].
            ///                 The eigenvectors are stored in the matrix columns.
            ///
            /// Result:
            ///     True, if the algorithm has converged.
            ///     False, if the algorithm hasn't converged (rare case).
            ///
            ///   -- ALGLIB --
            ///      Copyright 2005-2008 by Bochkanov Sergey
            ///
            /// public static bool alglib.smatrixevd(
            ///     double[,] a,
            ///     int n,
            ///     int zneeded,
            ///     bool isupper,
            ///     out double[] d,
            ///     out double[,] z)
            #endregion
            bool success = alglib.smatrixevd(A, A.ColSize, 1, false, out eigval, out eigvec);

            if (success == false)
            {
                HDebug.Assert(false);
                return(null);
            }
            return(new Tuple <MatrixByArr, Vector>(eigvec, eigval));
        }