Example #1
0
        // required implementations of abstract methods

        /// <inheritdoc />
        public override double this[int r, int c] {
            get {
                if ((r < 0) || (r >= rows))
                {
                    throw new ArgumentOutOfRangeException(nameof(r));
                }
                if ((c < 0) || (c >= cols))
                {
                    throw new ArgumentOutOfRangeException(nameof(c));
                }
                return(store[MatrixAlgorithms.GetIndex(offset, rowStride, colStride, r, c)]);
            }
            set {
                if ((r < 0) || (r >= rows))
                {
                    throw new ArgumentOutOfRangeException(nameof(r));
                }
                if ((c < 0) || (c >= cols))
                {
                    throw new ArgumentOutOfRangeException(nameof(c));
                }
                if (IsReadOnly)
                {
                    throw new InvalidOperationException();
                }
                store[MatrixAlgorithms.GetIndex(offset, rowStride, colStride, r, c)] = value;
            }
        }
Example #2
0
 /// <summary>
 /// Gets or sets an entry of the matrix.
 /// </summary>
 /// <param name="r">The (zero-based) row number.</param>
 /// <param name="c">The (zero-based) column number.</param>
 /// <returns>The value of the specified matrix entry M<sub>r c</sub>.</returns>
 public override double this[int r, int c] {
     get {
         CheckBounds(r, c);
         return(store[MatrixAlgorithms.GetIndex(offset, rowStride, colStride, r, c)]);
     }
     set {
         CheckBounds(r, c);
         if (IsReadOnly)
         {
             throw new InvalidOperationException();
         }
         store[MatrixAlgorithms.GetIndex(offset, rowStride, colStride, r, c)] = value;
     }
 }
Example #3
0
 /// <summary>
 /// Initializes a rectangular matrix from the given 2D array.
 /// </summary>
 /// <param name="source">The source 2D array.</param>
 public RectangularMatrix(double[,] source)
 {
     if (source == null)
     {
         throw new ArgumentNullException(nameof(source));
     }
     rows  = source.GetLength(0);
     cols  = source.GetLength(1);
     store = MatrixAlgorithms.AllocateStorage(rows, cols, ref offset, ref rowStride, ref colStride);
     for (int r = 0; r < rows; r++)
     {
         for (int c = 0; c < cols; c++)
         {
             store[MatrixAlgorithms.GetIndex(rows, cols, r, c)] = source[r, c];
         }
     }
 }
        // EIGENVALUE ALGORITHMS

        //

        public static Complex[] ReduceToRealSchurForm(double[] aStore, double[] qStore, int dimension)
        {
            // keep track of eigenvalues
            Complex[] eigenvalues = new Complex[dimension];

            // keep track of interations
            int count = 0;

            // isolate the upper and lower boundaries of the curent subproblem
            // p is the upper index, n the lower index

            int n = dimension - 1;

            while (n >= 0)
            {
                // move up the matrix from endpoint n, looking for subdiagonal elements negligible compared to the neighboring diagonal elements
                // if we find one, that reduces the problem to the submatrix between p and n
                int p = n;
                while (p > 0)
                {
                    double d = Math.Abs(MatrixAlgorithms.GetEntry(aStore, dimension, dimension, p, p)) + Math.Abs(MatrixAlgorithms.GetEntry(aStore, dimension, dimension, p - 1, p - 1));
                    double e = Math.Abs(MatrixAlgorithms.GetEntry(aStore, dimension, dimension, p, p - 1));

                    if (d + e == d)
                    {
                        //  double f = d * Math.Abs(MatrixAlgorithms.GetEntry(aStore, dimension, dimension, p, p) - MatrixAlgorithms.GetEntry(aStore, dimension, dimension, p - 1, p - 1));
                        //  double g = e * Math.Abs(MatrixAlgorithms.GetEntry(aStore, dimension, dimension, p - 1, p));

                        //  if (f + g == f) {
                        MatrixAlgorithms.SetEntry(aStore, dimension, dimension, p, p - 1, 0.0);
                        break;
                        //  }
                    }

                    p--;
                }

                /*
                 * if (p == n) {
                 *  // one eigenvalue
                 *  // reduce n and re-set count
                 * } else {
                 *  // compute m, matrix elements
                 *  // reduce n and re-set count
                 *  if (p == m) {
                 *      // two eigenvalues
                 *  } else {
                 *      // do step
                 *  }
                 * }
                 */

                //Print(a, dimension, p, n);

                // get the (indexes for) the entries in the trailing 2x2 matrix
                int m    = n - 1;
                int ammi = MatrixAlgorithms.GetIndex(dimension, dimension, m, m);
                int amni = MatrixAlgorithms.GetIndex(dimension, dimension, m, n);
                int anmi = MatrixAlgorithms.GetIndex(dimension, dimension, n, m);
                int anni = MatrixAlgorithms.GetIndex(dimension, dimension, n, n);

                if (n - p > 1)
                {
                    count++;
                    if (count > 32)
                    {
                        throw new NonconvergenceException();
                    }

                    double tr  = aStore[ammi] + aStore[anni];
                    double det = aStore[ammi] * aStore[anni] - aStore[amni] * aStore[anmi];

                    // ad hoc shift
                    if ((count == 8) || (count == 16) || (count == 24))
                    {
                        double w = Math.Abs(MatrixAlgorithms.GetEntry(aStore, dimension, dimension, n, n - 1)) +
                                   Math.Abs(MatrixAlgorithms.GetEntry(aStore, dimension, dimension, n - 1, n - 2));
                        tr  = 2.0 * w;
                        det = w * w;
                    }

                    FrancisTwoStep(aStore, qStore, dimension, p, n, tr, det);
                }
                else
                {
                    if (p == n)
                    {
                        eigenvalues[n] = aStore[anni];
                    }
                    else if (p == m)
                    {
                        double sn, cn;
                        TwoByTwoRealSchur(ref aStore[ammi], ref aStore[amni], ref aStore[anmi], ref aStore[anni], out sn, out cn, out eigenvalues[m], out eigenvalues[n]);

                        // Multiply A from left by the rotation matrix R
                        for (int cc = p + 2; cc < dimension; cc++)
                        {
                            int    i = MatrixAlgorithms.GetIndex(dimension, dimension, p, cc);
                            int    j = MatrixAlgorithms.GetIndex(dimension, dimension, p + 1, cc);
                            double t = aStore[i];
                            aStore[i] = cn * t + sn * aStore[j];
                            aStore[j] = cn * aStore[j] - sn * t;
                        }
                        // Multiply A from the right by R^T
                        for (int rr = 0; rr < p; rr++)
                        {
                            int    i = MatrixAlgorithms.GetIndex(dimension, dimension, rr, p);
                            int    j = MatrixAlgorithms.GetIndex(dimension, dimension, rr, p + 1);
                            double t = aStore[i];
                            aStore[i] = cn * t + sn * aStore[j];
                            aStore[j] = cn * aStore[j] - sn * t;
                        }
                        // Multiply Q^T from the left by R
                        if (qStore != null)
                        {
                            for (int rr = 0; rr < dimension; rr++)
                            {
                                int    i = MatrixAlgorithms.GetIndex(dimension, dimension, rr, p);
                                int    j = MatrixAlgorithms.GetIndex(dimension, dimension, rr, p + 1);
                                double t = qStore[i];
                                qStore[i] = cn * t + sn * qStore[j];
                                qStore[j] = cn * qStore[j] - sn * t;
                            }
                        }
                    }

                    n     = p - 1;
                    count = 0;
                }
            }

            return(eigenvalues);
        }