예제 #1
0
        /// <summary>Constructs a new Cholesky Decomposition.</summary>
        ///
        /// <param name="value">The matrix to be decomposed.</param>
        /// <param name="robust">True to perform a square-root free LDLt decomposition,
        /// false otherwise.</param>
        /// <param name="lowerTriangular">True to assume the <paramref name="value">value
        /// matrix</paramref> is a lower triangular symmetric matrix, false otherwise.</param>
        ///
        public CholeskyDecompositionF(Single[,] value, bool robust, bool lowerTriangular)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value", "Matrix cannot be null.");
            }

            if (value.GetLength(0) != value.GetLength(1))
            {
                throw new DimensionMismatchException("value", "Matrix is not square.");
            }

            if (robust)
            {
                LDLt(value); // Compute square-root free decomposition
            }
            else
            {
                LLt(value); // Compute standard Cholesky decomposition
            }

            if (lowerTriangular)
            {
                symmetric = true;
            }
        }
예제 #2
0
        public static Single[,] Process(Single[,] array, Int32 timeLength, Int32 valueLength)
        {
            var rs = new Single[timeLength, valueLength];

            var scale1 = (Single)array.GetLength(0) / timeLength;
            var scale2 = (Single)array.GetLength(1) / valueLength;

            for (var i = 0; i < timeLength; i++)
            {
                for (var j = 0; j < valueLength; j++)
                {
                    var d1        = i * scale1;
                    var d2        = j * scale2;
                    var n1        = (Int32)Math.Floor(d1);
                    var n2        = (Int32)Math.Floor(d2);
                    var leftUp    = (d1 - n1) * (d2 - n2);
                    var rightUp   = (n1 + 1 - d1) * (d2 - n2);
                    var rightDown = (n1 + 1 - d1) * (n2 + 1 - d2);
                    var leftDown  = (d1 - n1) * (n2 + 1 - d2);
                    rs[i, j] =
                        array[n1, n2] * rightDown +
                        array[n1 + 1, n2] * leftDown +
                        array[n1 + 1, n2 + 1] * leftUp +
                        array[n1, n2 + 1] * rightUp;
                }
            }

            return(rs);
        }
예제 #3
0
        //-----------------------------------------------------------------------------

        static public Single[] MinMax(Single[,] prmData)
        {
            Single min  = Single.MaxValue;
            Single max  = Single.MinValue;
            Int32  rows = prmData.GetLength(0);
            Int32  cols = prmData.GetLength(1);

            int i, j;

            for (i = 0; i < rows; i++)
            {
                for (j = 0; j < cols; j++)
                {
                    if (prmData[i, j] < min)
                    {
                        min = prmData[i, j];
                    }
                    if (prmData[i, j] > max)
                    {
                        max = prmData[i, j];
                    }
                }
            }
            return(new Single[2] {
                min, max
            });
        }
예제 #4
0
        /// <summary>
        ///   Solves a set of equation systems of type <c>A * X = B</c>.
        /// </summary>
        /// <param name="value">Right hand side matrix with as many rows as <c>A</c> and any number of columns.</param>
        /// <returns>Matrix <c>X</c> so that <c>L * U * X = B</c>.</returns>
        ///
        public Single[,] Solve(Single[,] value)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            if (value.GetLength(0) != rows)
            {
                throw new DimensionMismatchException("value", "The matrix should have the same number of rows as the decomposition.");
            }

            if (!Nonsingular)
            {
                throw new InvalidOperationException("Matrix is singular.");
            }


            // Copy right hand side with pivoting
            int count = value.GetLength(1);

            Single[,] X = value.Get(pivotVector, null);


            // Solve L*Y = B(piv,:)
            for (int k = 0; k < cols; k++)
            {
                for (int i = k + 1; i < cols; i++)
                {
                    for (int j = 0; j < count; j++)
                    {
                        X[i, j] -= X[k, j] * lu[i, k];
                    }
                }
            }

            // Solve U*X = Y;
            for (int k = cols - 1; k >= 0; k--)
            {
                for (int j = 0; j < count; j++)
                {
                    X[k, j] /= lu[k, k];
                }

                for (int i = 0; i < k; i++)
                {
                    for (int j = 0; j < count; j++)
                    {
                        X[i, j] -= X[k, j] * lu[i, k];
                    }
                }
            }

            return(X);
        }
예제 #5
0
        //-----------------------------------------------------------------------------

        static public Double StDev(Single[,] prmData, Double prmAvg)
        {
            Int32 rows = prmData.GetLength(0);
            Int32 cols = prmData.GetLength(1);

            int    i, j;
            Double sum = 0.0;

            for (i = 0; i < rows; i++)
            {
                for (j = 0; j < cols; j++)
                {
                    sum += Math.Pow(prmData[i, j] - prmAvg, 2);
                }
            }
            return(Math.Sqrt(sum / (rows * cols - 1)));
        }
예제 #6
0
        //-----------------------------------------------------------------------------

        static public Double Average(Single[,] prmData)
        {
            Int32 rows = prmData.GetLength(0);
            Int32 cols = prmData.GetLength(1);

            int    i, j;
            Double sum = 0.0;

            for (i = 0; i < rows; i++)
            {
                for (j = 0; j < cols; j++)
                {
                    sum += prmData[i, j];
                }
            }
            return(sum / rows * cols);
        }
예제 #7
0
        private unsafe void LDLt(Single[,] value)
        {
            n      = value.GetLength(0);
            L      = new Single[n, n];
            D      = new Single[n];
            robust = true;

            Single[,] a = value;

            Single[] v = new Single[n];
            this.positiveDefinite = true;
            this.symmetric        = true;

            Single d = D[0] = v[0] = a[0, 0];

            if (d == 0)
            {
                this.positiveDefinite = false;
            }

            for (int j = 1; j < n; j++)
            {
                L[j, 0] = a[j, 0] / d;
            }

            for (int j = 1; j < n; j++)
            {
                d = 0;
                for (int k = 0; k < j; k++)
                {
                    v[k] = L[j, k] * D[k];
                    d   += L[j, k] * v[k];
                }

                d = D[j] = v[j] = a[j, j] - d;

                // Use a tolerance for positive-definiteness
                this.positiveDefinite &= (d > (Single)1e-14 * Math.Abs(a[j, j]));

                for (int k = j + 1; k < n; k++)
                {
                    Single s = 0;
                    for (int i = 0; i < j; i++)
                    {
                        s += L[k, i] * v[i];
                    }

                    L[k, j] = (a[k, j] - s) / d;

                    this.symmetric = this.symmetric & (a[k, j] == a[j, k]);
                }
            }

            for (int i = 0; i < n; i++)
            {
                L[i, i] += 1;
            }
        }
        /// <summary>
        ///   Construct an eigenvalue decomposition.</summary>
        /// <param name="value">
        ///   The matrix to be decomposed.</param>
        /// <param name="assumeSymmetric">
        ///   Defines if the matrix should be assumed as being symmetric
        ///   regardless if it is or not. Default is <see langword="false"/>.</param>
        /// <param name="inPlace">
        ///   Pass <see langword="true"/> to perform the decomposition in place. The matrix
        ///   <paramref name="value"/> will be destroyed in the process, resulting in less
        ///   memory comsumption.</param>
        public EigenvalueDecompositionF(Single[,] value, bool assumeSymmetric, bool inPlace)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value", "Matrix cannot be null.");
            }

            if (value.GetLength(0) != value.GetLength(1))
            {
                throw new ArgumentException("Matrix is not a square matrix.", "value");
            }

            n = value.GetLength(1);
            V = new Single[n, n];
            d = new Single[n];
            e = new Single[n];


            this.symmetric = assumeSymmetric;

            if (this.symmetric)
            {
                V = inPlace ? value : (Single[, ])value.Clone();

                // Tridiagonalize.
                this.tred2();

                // Diagonalize.
                this.tql2();
            }
            else
            {
                H = inPlace ? value : (Single[, ])value.Clone();

                ort = new Single[n];

                // Reduce to Hessenberg form.
                this.orthes();

                // Reduce Hessenberg to real Schur form.
                this.hqr2();
            }
        }
예제 #9
0
        //------------------------------------------------------------------

        protected void Write(BinaryWriter wrt, Single[,] prmPoints)
        {
            Int32 rows    = prmPoints.GetLength(0);
            Int32 columns = prmPoints.GetLength(1);

            Int32 length = rows * columns;

            Byte[] byteStream;

            for (int i = 0; i < rows; i++)
            {
                byteStream = new Byte[columns * sizeof(Single)];
                for (int j = 0; j < columns; j++)
                {
                    Array.Copy(BitConverter.GetBytes(prmPoints[i, j]), 0, byteStream, j * sizeof(Single), sizeof(Single));
                }
                wrt.Write(byteStream);
            }
        }
예제 #10
0
        /// <summary>
        ///   Solves a set of equation systems of type <c>X * A = B</c>.
        /// </summary>
        /// <param name="value">Right hand side matrix with as many columns as <c>A</c> and any number of rows.</param>
        /// <returns>Matrix <c>X</c> so that <c>X * L * U = A</c>.</returns>
        ///
        public Single[,] SolveTranspose(Single[,] value)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            if (value.GetLength(0) != rows)
            {
                throw new DimensionMismatchException("value", "The matrix should have the same number of rows as the decomposition.");
            }

            if (!Nonsingular)
            {
                throw new SingularMatrixException("Matrix is singular.");
            }


            // Copy right hand side with pivoting
            var X = value.Get(null, pivotVector);

            int count = X.GetLength(1);

            // Solve L*Y = B(piv,:)
            for (int k = 0; k < rows; k++)
            {
                for (int i = k + 1; i < rows; i++)
                {
                    for (int j = 0; j < count; j++)
                    {
                        X[j, i] -= X[j, k] * lu[i, k];
                    }
                }
            }

            // Solve U*X = Y;
            for (int k = rows - 1; k >= 0; k--)
            {
                for (int j = 0; j < count; j++)
                {
                    X[j, k] /= lu[k, k];
                }

                for (int i = 0; i < k; i++)
                {
                    for (int j = 0; j < count; j++)
                    {
                        X[j, i] -= X[j, k] * lu[i, k];
                    }
                }
            }

            return(X);
        }
예제 #11
0
        private unsafe void LLt(Single[,] value)
        {
            n = value.GetLength(0);
            L = new Single[n, n];
            D = new Single[n];

            for (int i = 0; i < D.Length; i++)
            {
                D[i] = 1;
            }

            robust = false;

            Single[,] a = value;

            this.positiveDefinite = true;
            this.symmetric        = true;

            fixed(Single *ptrL = L)
            {
                for (int j = 0; j < n; j++)
                {
                    Single *Lrowj = ptrL + j * n;
                    Single  d     = 0;
                    for (int k = 0; k < j; k++)
                    {
                        Single *Lrowk = ptrL + k * n;

                        Single s = 0;
                        for (int i = 0; i < k; i++)
                        {
                            s += Lrowk[i] * Lrowj[i];
                        }

                        Lrowj[k] = s = (a[j, k] - s) / Lrowk[k];
                        d       += s * s;

                        this.symmetric = this.symmetric & (a[k, j] == a[j, k]);
                    }

                    d = a[j, j] - d;

                    // Use a tolerance for positive-definiteness
                    this.positiveDefinite &= (d > (Single)1e-14 * Math.Abs(a[j, j]));

                    Lrowj[j] = (Single)System.Math.Sqrt((double)System.Math.Max(d, 0));

                    for (int k = j + 1; k < n; k++)
                    {
                        Lrowj[k] = 0;
                    }
                }
            }
        }
        private void WriteDistance(Single[,] result, string path)
        {
            var p_size = result.GetLength(0);
            var d_size = result.GetLength(1);

            using (var writer = new StreamWriter(path))
            {
                writer.WriteLine("{");
                for (var p = 0; p < p_size; p++)
                {
                    writer.Write("{{{0:0}", result[p, 0]);
                    for (var d = 1; d < d_size; d++)
                    {
                        writer.Write(",{0:0}", result[p, d]);
                    }
                    writer.WriteLine("},");
                }
                writer.WriteLine("};");
            }
        }
예제 #13
0
        //-----------------------------------------------------------------------------

        static public Double TorAverage(Single[,] prmData)
        {
            Int32 rows = prmData.GetLength(0);
            Int32 cols = prmData.GetLength(1);

            int    i, j;
            Double count = 0.0;
            Double sum   = 0.0;

            for (i = 0; i < rows; i++)
            {
                for (j = 0; j < cols; j++)
                {
                    if (prmData[i, j] != c_TorNullHeight)
                    {
                        sum += prmData[i, j];
                        count++;
                    }
                }
            }
            return(count > 0 ? sum / count : c_TorNullHeight);
        }
예제 #14
0
        //-----------------------------------------------------------------------------

        static public Double TorStDev(Single[,] prmData, Double prmAvg)
        {
            Int32 rows = prmData.GetLength(0);
            Int32 cols = prmData.GetLength(1);

            int    i, j;
            Double sum   = 0.0;
            Double count = 0.0;

            for (i = 0; i < rows; i++)
            {
                for (j = 0; j < cols; j++)
                {
                    if (prmData[i, j] != c_TorNullHeight)
                    {
                        sum += Math.Pow(prmData[i, j] - prmAvg, 2);
                        count++;
                    }
                }
            }
            return(count > 1 ? Math.Sqrt(sum / (count - 1)) : c_TorNullHeight);
        }
예제 #15
0
        /// <summary>
        ///   Creates a new Cholesky decomposition directly from
        ///   an already computed left triangular matrix <c>L</c>.
        /// </summary>
        /// <param name="leftTriangular">The left triangular matrix from a Cholesky decomposition.</param>
        ///
        public static CholeskyDecompositionF FromLeftTriangularMatrix(Single[,] leftTriangular)
        {
            var chol = new CholeskyDecompositionF();

            chol.n                = leftTriangular.GetLength(0);
            chol.L                = leftTriangular;
            chol.symmetric        = true;
            chol.positiveDefinite = true;
            chol.robust           = false;
            chol.D                = new Single[chol.n];
            for (int i = 0; i < chol.D.Length; i++)
            {
                chol.D[i] = 1;
            }

            return(chol);
        }
예제 #16
0
        /// <summary>Solves a set of equation systems of type <c>A * X = B</c>.</summary>
        /// <param name="value">Right hand side matrix with as many rows as <c>A</c> and any number of columns.</param>
        /// <returns>Matrix <c>X</c> so that <c>L * L' * X = B</c>.</returns>
        /// <exception cref="T:System.ArgumentException">Matrix dimensions do not match.</exception>
        /// <exception cref="T:System.NonSymmetricMatrixException">Matrix is not symmetric.</exception>
        /// <exception cref="T:System.NonPositiveDefiniteMatrixException">Matrix is not positive-definite.</exception>
        /// <param name="inPlace">True to compute the solving in place, false otherwise.</param>
        ///
        public Single[,] Solve(Single[,] value, bool inPlace)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            if (value.GetLength(0) != n)
            {
                throw new ArgumentException("Argument matrix should have the same number of rows as the decomposed matrix.", "value");
            }

            if (!symmetric)
            {
                throw new NonSymmetricMatrixException("Decomposed matrix is not symmetric.");
            }

            if (!robust && !positiveDefinite)
            {
                throw new NonPositiveDefiniteMatrixException("Decomposed matrix is not positive definite.");
            }


            int count = value.GetLength(1);

            Single[,] B = inPlace ? value : (Single[, ])value.Clone();


            // Solve L*Y = B;
            for (int k = 0; k < n; k++)
            {
                for (int j = 0; j < count; j++)
                {
                    for (int i = 0; i < k; i++)
                    {
                        B[k, j] -= B[i, j] * L[k, i];
                    }

                    B[k, j] /= L[k, k];
                }
            }

            if (robust)
            {
                for (int k = 0; k < n; k++)
                {
                    for (int j = 0; j < count; j++)
                    {
                        B[k, j] /= D[k];
                    }
                }
            }

            // Solve L'*X = Y;
            for (int k = n - 1; k >= 0; k--)
            {
                for (int j = 0; j < count; j++)
                {
                    for (int i = k + 1; i < n; i++)
                    {
                        B[k, j] -= B[i, j] * L[i, k];
                    }

                    B[k, j] /= L[k, k];
                }
            }

            return(B);
        }
예제 #17
0
        /// <summary>Constructs a QR decomposition.</summary>
        /// <param name="value">The matrix A to be decomposed.</param>
        /// <param name="transpose">True if the decomposition should be performed on
        /// the transpose of A rather than A itself, false otherwise. Default is false.</param>
        public QrDecompositionF(Single[,] value, bool transpose)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value", "Matrix cannot be null.");
            }

            if ((!transpose && value.GetLength(0) < value.GetLength(1)) ||
                (transpose && value.GetLength(1) < value.GetLength(0)))
            {
                throw new ArgumentException("Matrix has more columns than rows.", "value");
            }

            this.qr = transpose ? value.Transpose() : (Single[, ])value.Clone();

            int rows = qr.GetLength(0);
            int cols = qr.GetLength(1);

            this.Rdiag = new Single[cols];

            for (int k = 0; k < cols; k++)
            {
                // Compute 2-norm of k-th column without under/overflow.
                Single nrm = 0;
                for (int i = k; i < rows; i++)
                {
                    nrm = Tools.Hypotenuse(nrm, qr[i, k]);
                }

                if (nrm != 0)
                {
                    // Form k-th Householder vector.
                    if (qr[k, k] < 0)
                    {
                        nrm = -nrm;
                    }

                    for (int i = k; i < rows; i++)
                    {
                        qr[i, k] /= nrm;
                    }

                    qr[k, k] += 1;

                    // Apply transformation to remaining columns.
                    for (int j = k + 1; j < cols; j++)
                    {
                        Single s = 0;

                        for (int i = k; i < rows; i++)
                        {
                            s += qr[i, k] * qr[i, j];
                        }

                        s = -s / qr[k, k];

                        for (int i = k; i < rows; i++)
                        {
                            qr[i, j] += s * qr[i, k];
                        }
                    }
                }

                this.Rdiag[k] = -nrm;
            }
        }
예제 #18
0
        /// <summary>Least squares solution of <c>X * A = B</c></summary>
        /// <param name="value">Right-hand-side matrix with as many columns as <c>A</c> and any number of rows.</param>
        /// <returns>A matrix that minimized the two norm of <c>X * Q * R - B</c>.</returns>
        /// <exception cref="T:System.ArgumentException">Matrix column dimensions must be the same.</exception>
        /// <exception cref="T:System.InvalidOperationException">Matrix is rank deficient.</exception>
        public Single[,] SolveTranspose(Single[,] value)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value", "Matrix cannot be null.");
            }

            if (value.GetLength(1) != qr.GetLength(0))
            {
                throw new ArgumentException("Matrix row dimensions must agree.");
            }

            if (!this.FullRank)
            {
                throw new InvalidOperationException("Matrix is rank deficient.");
            }

            // Copy right hand side
            int count = value.GetLength(0);
            var X     = value.Transpose();
            int m     = qr.GetLength(0);
            int n     = qr.GetLength(1);

            // Compute Y = transpose(Q)*B
            for (int k = 0; k < n; k++)
            {
                for (int j = 0; j < count; j++)
                {
                    Single s = 0;

                    for (int i = k; i < m; i++)
                    {
                        s += qr[i, k] * X[i, j];
                    }

                    s = -s / qr[k, k];

                    for (int i = k; i < m; i++)
                    {
                        X[i, j] += s * qr[i, k];
                    }
                }
            }

            // Solve R*X = Y;
            for (int k = n - 1; k >= 0; k--)
            {
                for (int j = 0; j < count; j++)
                {
                    X[k, j] /= Rdiag[k];
                }

                for (int i = 0; i < k; i++)
                {
                    for (int j = 0; j < count; j++)
                    {
                        X[i, j] -= X[k, j] * qr[i, k];
                    }
                }
            }

            var r = new Single[count, n];

            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < count; j++)
                {
                    r[j, i] = X[i, j];
                }
            }

            return(r);
        }
예제 #19
0
        /// <summary>
        ///   Constructs a new LU decomposition.
        /// </summary>
        /// <param name="value">The matrix A to be decomposed.</param>
        /// <param name="transpose">True if the decomposition should be performed on
        /// the transpose of A rather than A itself, false otherwise. Default is false.</param>
        /// <param name="inPlace">True if the decomposition should be performed over the
        /// <paramref name="value"/> matrix rather than on a copy of it. If true, the
        /// matrix will be destroyed during the decomposition. Default is false.</param>
        ///
        public LuDecompositionF(Single[,] value, bool transpose, bool inPlace)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value", "Matrix cannot be null.");
            }

            if (transpose)
            {
                this.lu = value.Transpose(inPlace);
            }
            else
            {
                this.lu = inPlace ? value : (Single[, ])value.Clone();
            }

            this.rows      = lu.GetLength(0);
            this.cols      = lu.GetLength(1);
            this.pivotSign = 1;

            this.pivotVector = new int[rows];
            for (int i = 0; i < rows; i++)
            {
                pivotVector[i] = i;
            }

            var LUcolj = new Single[rows];


            unsafe
            {
                fixed(Single *LU = lu)
                {
                    // Outer loop.
                    for (int j = 0; j < cols; j++)
                    {
                        // Make a copy of the j-th column to localize references.
                        for (int i = 0; i < rows; i++)
                        {
                            LUcolj[i] = lu[i, j];
                        }

                        // Apply previous transformations.
                        for (int i = 0; i < rows; i++)
                        {
                            Single s = 0;

                            // Most of the time is spent in
                            // the following dot product:
                            int     kmax   = Math.Min(i, j);
                            Single *LUrowi = &LU[i * cols];
                            for (int k = 0; k < kmax; k++)
                            {
                                s += LUrowi[k] * LUcolj[k];
                            }

                            LUrowi[j] = LUcolj[i] -= s;
                        }

                        // Find pivot and exchange if necessary.
                        int p = j;
                        for (int i = j + 1; i < rows; i++)
                        {
                            if (Math.Abs(LUcolj[i]) > Math.Abs(LUcolj[p]))
                            {
                                p = i;
                            }
                        }

                        if (p != j)
                        {
                            for (int k = 0; k < cols; k++)
                            {
                                var t = lu[p, k];
                                lu[p, k] = lu[j, k];
                                lu[j, k] = t;
                            }

                            int v = pivotVector[p];
                            pivotVector[p] = pivotVector[j];
                            pivotVector[j] = v;

                            pivotSign = -pivotSign;
                        }

                        // Compute multipliers.
                        if (j < rows && lu[j, j] != 0)
                        {
                            for (int i = j + 1; i < rows; i++)
                            {
                                lu[i, j] /= lu[j, j];
                            }
                        }
                    }
                }
            }
        }
예제 #20
0
        /// <summary>
        ///   Construct an eigenvalue decomposition.</summary>
        ///
        /// <param name="value">
        ///   The matrix to be decomposed.</param>
        /// <param name="assumeSymmetric">
        ///   Defines if the matrix should be assumed as being symmetric
        ///   regardless if it is or not. Default is <see langword="false"/>.</param>
        /// <param name="inPlace">
        ///   Pass <see langword="true"/> to perform the decomposition in place. The matrix
        ///   <paramref name="value"/> will be destroyed in the process, resulting in less
        ///   memory comsumption.</param>
        /// <param name="sort">
        ///   Pass <see langword="true"/> to sort the eigenvalues and eigenvectors at the end
        ///   of the decomposition.</param>
        ///
        public EigenvalueDecompositionF(Single[,] value, bool assumeSymmetric,
                                        bool inPlace = false, bool sort = false)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value", "Matrix cannot be null.");
            }

            if (value.GetLength(0) != value.GetLength(1))
            {
                throw new ArgumentException("Matrix is not a square matrix.", "value");
            }

            n = value.GetLength(1);
            V = new Single[n, n];
            d = new Single[n];
            e = new Single[n];


            this.symmetric = assumeSymmetric;

            if (this.symmetric)
            {
                V = inPlace ? value : (Single[, ])value.Clone();

                // Tridiagonalize.
                this.tred2();

                // Diagonalize.
                this.tql2();
            }
            else
            {
                H = inPlace ? value : (Single[, ])value.Clone();

                ort = new Single[n];

                // Reduce to Hessenberg form.
                this.orthes();

                // Reduce Hessenberg to real Schur form.
                this.hqr2();
            }

            if (sort)
            {
                // Sort eigenvalues and vectors in descending order
                var idx = Vector.Range(n);
                Array.Sort(idx, (i, j) =>
                {
                    if (Math.Abs(d[i]) == Math.Abs(d[j]))
                    {
                        return(-Math.Abs(e[i]).CompareTo(Math.Abs(e[j])));
                    }
                    return(-Math.Abs(d[i]).CompareTo(Math.Abs(d[j])));
                });

                this.d = this.d.Get(idx);
                this.e = this.e.Get(idx);
                this.V = this.V.Get(null, idx);
            }
        }
예제 #21
0
    private void GoFillSomeTestValues(Hashtable hshArrayValue)
    {
        ArrayList alst = new ArrayList();

        for (int ii = 0; ii < bArr.GetLength(0); ii++)
        {
            for (int jj = 0; jj < bArr.GetLength(1); jj++)
            {
                alst.Add(bArr[ii, jj]);
            }
        }
        hshArrayValue.Add(typeof(Boolean).Name, alst);
        alst = new ArrayList();
        for (int ii = 0; ii < cArr.GetLength(0); ii++)
        {
            for (int jj = 0; jj < cArr.GetLength(1); jj++)
            {
                alst.Add(cArr[ii, jj]);
            }
        }
        hshArrayValue.Add(typeof(Char).Name, alst);
        alst = new ArrayList();
        for (int ii = 0; ii < sbtArr.GetLength(0); ii++)
        {
            for (int jj = 0; jj < sbtArr.GetLength(1); jj++)
            {
                alst.Add(sbtArr[ii, jj]);
            }
        }
        hshArrayValue.Add(typeof(SByte).Name, alst);
        alst = new ArrayList();
        for (int ii = 0; ii < btArr.GetLength(0); ii++)
        {
            for (int jj = 0; jj < btArr.GetLength(1); jj++)
            {
                alst.Add(btArr[ii, jj]);
            }
        }
        hshArrayValue.Add(typeof(Byte).Name, alst);
        alst = new ArrayList();
        for (int ii = 0; ii < i16Arr.GetLength(0); ii++)
        {
            for (int jj = 0; jj < i16Arr.GetLength(1); jj++)
            {
                alst.Add(i16Arr[ii, jj]);
            }
        }
        hshArrayValue.Add(typeof(Int16).Name, alst);
        alst = new ArrayList();
        for (int ii = 0; ii < i32Arr.GetLength(0); ii++)
        {
            for (int jj = 0; jj < i32Arr.GetLength(1); jj++)
            {
                alst.Add(i32Arr[ii, jj]);
            }
        }
        hshArrayValue.Add(typeof(Int32).Name, alst);
        alst = new ArrayList();
        for (int ii = 0; ii < i64Arr.GetLength(0); ii++)
        {
            for (int jj = 0; jj < i64Arr.GetLength(1); jj++)
            {
                alst.Add(i64Arr[ii, jj]);
            }
        }
        hshArrayValue.Add(typeof(Int64).Name, alst);
        alst = new ArrayList();
        for (int ii = 0; ii < fArr.GetLength(0); ii++)
        {
            for (int jj = 0; jj < fArr.GetLength(1); jj++)
            {
                alst.Add(fArr[ii, jj]);
            }
        }
        hshArrayValue.Add(typeof(Single).Name, alst);
        alst = new ArrayList();
        for (int ii = 0; ii < dArr.GetLength(0); ii++)
        {
            for (int jj = 0; jj < dArr.GetLength(1); jj++)
            {
                alst.Add(dArr[ii, jj]);
            }
        }
        hshArrayValue.Add(typeof(Double).Name, alst);
        alst = new ArrayList();
        for (int ii = 0; ii < strArr.GetLength(0); ii++)
        {
            for (int jj = 0; jj < strArr.GetLength(1); jj++)
            {
                alst.Add(strArr[ii, jj]);
            }
        }
        hshArrayValue.Add(typeof(String).Name, alst);
    }
예제 #22
0
        /// <summary>
        ///   Solves a linear equation system of the form AX = B.
        /// </summary>
        /// <param name="value">Parameter B from the equation AX = B.</param>
        /// <returns>The solution X from equation AX = B.</returns>
        public Single[,] Solve(Single[,] value)
        {
            // Additionally an important property is that if there does not exists a solution
            // when the matrix A is singular but replacing 1/Li with 0 will provide a solution
            // that minimizes the residue |AX -Y|. SVD finds the least squares best compromise
            // solution of the linear equation system. Interestingly SVD can be also used in an
            // over-determined system where the number of equations exceeds that of the parameters.

            // L is a diagonal matrix with non-negative matrix elements having the same
            // dimension as A, Wi ? 0. The diagonal elements of L are the singular values of matrix A.

            Single[,] Y = value;

            // Create L*, which is a diagonal matrix with elements
            //    L*[i] = 1/L[i]  if L[i] < e, else 0,
            // where e is the so-called singularity threshold.

            // In other words, if L[i] is zero or close to zero (smaller than e),
            // one must replace 1/L[i] with 0. The value of e depends on the precision
            // of the hardware. This method can be used to solve linear equations
            // systems even if the matrices are singular or close to singular.

            //singularity threshold
            Single e = this.Threshold;


            int scols = s.Length;
            var Ls    = new Single[scols, scols];

            for (int i = 0; i < s.Length; i++)
            {
                if (System.Math.Abs(s[i]) <= e)
                {
                    Ls[i, i] = 0;
                }
                else
                {
                    Ls[i, i] = 1 / s[i];
                }
            }

            //(V x L*) x Ut x Y
            var VL = v.Multiply(Ls);

            //(V x L* x Ut) x Y
            int vrows = v.GetLength(0);
            int urows = u.GetLength(0);
            var VLU   = new Single[vrows, scols];

            for (int i = 0; i < vrows; i++)
            {
                for (int j = 0; j < urows; j++)
                {
                    Single sum = 0;
                    for (int k = 0; k < urows; k++)
                    {
                        sum += VL[i, k] * u[j, k];
                    }
                    VLU[i, j] = sum;
                }
            }

            //(V x L* x Ut x Y)
            return(VLU.Multiply(Y));
        }
예제 #23
0
        /// <summary>
        ///   Constructs a new singular value decomposition.
        /// </summary>
        ///
        /// <param name="value">
        ///   The matrix to be decomposed.</param>
        /// <param name="computeLeftSingularVectors">
        ///   Pass <see langword="true"/> if the left singular vector matrix U
        ///   should be computed. Pass <see langword="false"/> otherwise. Default
        ///   is <see langword="true"/>.</param>
        /// <param name="computeRightSingularVectors">
        ///   Pass <see langword="true"/> if the right singular vector matrix V
        ///   should be computed. Pass <see langword="false"/> otherwise. Default
        ///   is <see langword="true"/>.</param>
        /// <param name="autoTranspose">
        ///   Pass <see langword="true"/> to automatically transpose the value matrix in
        ///   case JAMA's assumptions about the dimensionality of the matrix are violated.
        ///   Pass <see langword="false"/> otherwise. Default is <see langword="false"/>.</param>
        /// <param name="inPlace">
        ///   Pass <see langword="true"/> to perform the decomposition in place. The matrix
        ///   <paramref name="value"/> will be destroyed in the process, resulting in less
        ///   memory comsumption.</param>
        ///
        public unsafe SingularValueDecompositionF(Single[,] value,
                                                  bool computeLeftSingularVectors, bool computeRightSingularVectors, bool autoTranspose, bool inPlace)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value", "Matrix cannot be null.");
            }

            Single[,] a;
            m = value.GetLength(0); // rows
            n = value.GetLength(1); // cols

            if (m == 0 || n == 0)
            {
                throw new ArgumentException("Matrix does not have any rows or columns.", "value");
            }



            if (m < n)              // Check if we are violating JAMA's assumption
            {
                if (!autoTranspose) // Yes, check if we should correct it
                {
                    // Warning! This routine is not guaranteed to work when A has less rows
                    //  than columns. If this is the case, you should compute SVD on the
                    //  transpose of A and then swap the left and right eigenvectors.

                    // However, as the solution found can still be useful, the exception below
                    // will not be thrown, and only a warning will be output in the trace.

                    // throw new ArgumentException("Matrix should have more rows than columns.");

                    System.Diagnostics.Trace.WriteLine(
                        "WARNING: Computing SVD on a matrix with more columns than rows.");

                    // Proceed anyway
                    a = inPlace ? value : (Single[, ])value.Clone();
                }
                else
                {
                    // Transposing and swapping
                    a       = value.Transpose(inPlace && m == n);
                    m       = value.GetLength(1);
                    n       = value.GetLength(0);
                    swapped = true;

                    bool aux = computeLeftSingularVectors;
                    computeLeftSingularVectors  = computeRightSingularVectors;
                    computeRightSingularVectors = aux;
                }
            }
            else
            {
                // Input matrix is ok
                a = inPlace ? value : (Single[, ])value.Clone();
            }


            int nu = System.Math.Min(m, n);
            int ni = System.Math.Min(m + 1, n);

            s = new Single[ni];
            u = new Single[m, nu];
            v = new Single[n, n];
            Single[] e     = new Single[n];
            Single[] work  = new Single[m];
            bool     wantu = computeLeftSingularVectors;
            bool     wantv = computeRightSingularVectors;

            fixed(Single *U = u)
            fixed(Single * V = v)
            fixed(Single * A = a)
            {
                // Will store ordered sequence of indices after sorting.
                si = new int[ni]; for (int i = 0; i < ni; i++)
                {
                    si[i] = i;
                }


                // Reduce A to bidiagonal form, storing the diagonal elements in s and the super-diagonal elements in e.
                int nct = System.Math.Min(m - 1, n);
                int nrt = System.Math.Max(0, System.Math.Min(n - 2, m));

                for (int k = 0; k < System.Math.Max(nct, nrt); k++)
                {
                    if (k < nct)
                    {
                        // Compute the transformation for the k-th column and place the k-th diagonal in s[k].
                        // Compute 2-norm of k-th column without under/overflow.
                        s[k] = 0;
                        for (int i = k; i < m; i++)
                        {
                            s[k] = Accord.Math.Tools.Hypotenuse(s[k], a[i, k]);
                        }

                        if (s[k] != 0)
                        {
                            if (a[k, k] < 0)
                            {
                                s[k] = -s[k];
                            }

                            for (int i = k; i < m; i++)
                            {
                                a[i, k] /= s[k];
                            }

                            a[k, k] += 1;
                        }

                        s[k] = -s[k];
                    }

                    for (int j = k + 1; j < n; j++)
                    {
                        Single *ptr_ak = A + k * n + k; // A[k,k]
                        Single *ptr_aj = A + k * n + j; // A[k,j]

                        if ((k < nct) & (s[k] != 0))
                        {
                            // Apply the transformation.
                            Single  t  = 0;
                            Single *ak = ptr_ak;
                            Single *aj = ptr_aj;

                            for (int i = k; i < m; i++)
                            {
                                t  += (*ak) * (*aj);
                                ak += n; aj += n;
                            }

                            t  = -t / *ptr_ak;
                            ak = ptr_ak;
                            aj = ptr_aj;

                            for (int i = k; i < m; i++)
                            {
                                *aj += t * (*ak);
                                ak += n; aj += n;
                            }
                        }

                        // Place the k-th row of A into e for the subsequent calculation of the row transformation.
                        e[j] = *ptr_aj;
                    }


                    if (wantu & (k < nct))
                    {
                        // Place the transformation in U for subsequent back
                        // multiplication.
                        for (int i = k; i < m; i++)
                        {
                            u[i, k] = a[i, k];
                        }
                    }

                    if (k < nrt)
                    {
                        // Compute the k-th row transformation and place the k-th super-diagonal in e[k].
                        // Compute 2-norm without under/overflow.
                        e[k] = 0;
                        for (int i = k + 1; i < n; i++)
                        {
                            e[k] = Accord.Math.Tools.Hypotenuse(e[k], e[i]);
                        }

                        if (e[k] != 0)
                        {
                            if (e[k + 1] < 0)
                            {
                                e[k] = -e[k];
                            }

                            for (int i = k + 1; i < n; i++)
                            {
                                e[i] /= e[k];
                            }

                            e[k + 1] += 1;
                        }

                        e[k] = -e[k];
                        if ((k + 1 < m) & (e[k] != 0))
                        {
                            // Apply the transformation.
                            for (int i = k + 1; i < m; i++)
                            {
                                work[i] = 0;
                            }

                            int k1 = k + 1;
                            for (int i = k1; i < m; i++)
                            {
                                Single *ai = A + (i * n) + k1;
                                for (int j = k1; j < n; j++, ai++)
                                {
                                    work[i] += e[j] * (*ai);
                                }
                            }

                            for (int j = k1; j < n; j++)
                            {
                                Single  t  = -e[j] / e[k1];
                                Single *aj = A + (k1 * n) + j;
                                for (int i = k1; i < m; i++, aj += n)
                                {
                                    *aj += t * work[i];
                                }
                            }
                        }

                        if (wantv)
                        {
                            // Place the transformation in V for subsequent back multiplication.
                            for (int i = k + 1; i < n; i++)
                            {
                                v[i, k] = e[i];
                            }
                        }
                    }
                }

                // Set up the final bidiagonal matrix or order p.
                int p = System.Math.Min(n, m + 1);

                if (nct < n)
                {
                    s[nct] = a[nct, nct];
                }
                if (m < p)
                {
                    s[p - 1] = 0;
                }
                if (nrt + 1 < p)
                {
                    e[nrt] = a[nrt, p - 1];
                }
                e[p - 1] = 0;

                // If required, generate U.
                if (wantu)
                {
                    for (int j = nct; j < nu; j++)
                    {
                        for (int i = 0; i < m; i++)
                        {
                            u[i, j] = 0;
                        }
                        u[j, j] = 1;
                    }

                    for (int k = nct - 1; k >= 0; k--)
                    {
                        if (s[k] != 0)
                        {
                            Single *ptr_uk = U + k * nu + k; // u[k,k]

                            Single *uk, uj;
                            for (int j = k + 1; j < nu; j++)
                            {
                                Single *ptr_uj = U + k * nu + j; // u[k,j]

                                Single t = 0;
                                uk = ptr_uk;
                                uj = ptr_uj;

                                for (int i = k; i < m; i++)
                                {
                                    t  += *uk * *uj;
                                    uk += nu; uj += nu;
                                }

                                t = -t / *ptr_uk;

                                uk = ptr_uk; uj = ptr_uj;
                                for (int i = k; i < m; i++)
                                {
                                    *uj += t * (*uk);
                                    uk += nu; uj += nu;
                                }
                            }

                            uk = ptr_uk;
                            for (int i = k; i < m; i++)
                            {
                                *uk = -(*uk);
                                uk += nu;
                            }

                            u[k, k] = 1 + u[k, k];
                            for (int i = 0; i < k - 1; i++)
                            {
                                u[i, k] = 0;
                            }
                        }
                        else
                        {
                            for (int i = 0; i < m; i++)
                            {
                                u[i, k] = 0;
                            }
                            u[k, k] = 1;
                        }
                    }
                }

                // If required, generate V.
                if (wantv)
                {
                    for (int k = n - 1; k >= 0; k--)
                    {
                        if ((k < nrt) & (e[k] != 0))
                        {
                            // TODO: The following is a pseudo correction to make SVD
                            //  work on matrices with n > m (less rows than columns).

                            // For the proper correction, compute the decomposition of the
                            //  transpose of A and swap the left and right eigenvectors

                            // Original line:
                            //   for (int j = k + 1; j < nu; j++)
                            // Pseudo correction:
                            //   for (int j = k + 1; j < n; j++)

                            for (int j = k + 1; j < n; j++)           // pseudo-correction
                            {
                                Single *ptr_vk = V + (k + 1) * n + k; // v[k + 1, k]
                                Single *ptr_vj = V + (k + 1) * n + j; // v[k + 1, j]

                                Single  t  = 0;
                                Single *vk = ptr_vk;
                                Single *vj = ptr_vj;

                                for (int i = k + 1; i < n; i++)
                                {
                                    t  += *vk * *vj;
                                    vk += n; vj += n;
                                }

                                t = -t / *ptr_vk;

                                vk = ptr_vk; vj = ptr_vj;
                                for (int i = k + 1; i < n; i++)
                                {
                                    *vj += t * (*vk);
                                    vk += n; vj += n;
                                }
                            }
                        }

                        for (int i = 0; i < n; i++)
                        {
                            v[i, k] = 0;
                        }
                        v[k, k] = 1;
                    }
                }

                // Main iteration loop for the singular values.
                int pp   = p - 1;
                int iter = 0;

                while (p > 0)
                {
                    int k, kase;

                    // Here is where a test for too many iterations would go.

                    // This section of the program inspects for
                    // negligible elements in the s and e arrays.  On
                    // completion the variables kase and k are set as follows.

                    // kase = 1     if s(p) and e[k-1] are negligible and k<p
                    // kase = 2     if s(k) is negligible and k<p
                    // kase = 3     if e[k-1] is negligible, k<p, and
                    //              s(k), ..., s(p) are not negligible (qr step).
                    // kase = 4     if e(p-1) is negligible (convergence).

                    for (k = p - 2; k >= -1; k--)
                    {
                        if (k == -1)
                        {
                            break;
                        }

                        if (System.Math.Abs(e[k]) <=
                            tiny + eps * (System.Math.Abs(s[k]) + System.Math.Abs(s[k + 1])))
                        {
                            e[k] = 0;
                            break;
                        }
                    }

                    if (k == p - 2)
                    {
                        kase = 4;
                    }
                    else
                    {
                        int ks;
                        for (ks = p - 1; ks >= k; ks--)
                        {
                            if (ks == k)
                            {
                                break;
                            }

                            Single t = (ks != p ? System.Math.Abs(e[ks]) : 0) +
                                       (ks != k + 1 ? System.Math.Abs(e[ks - 1]) : 0);
                            if (System.Math.Abs(s[ks]) <= tiny + eps * t)
                            {
                                s[ks] = 0;
                                break;
                            }
                        }

                        if (ks == k)
                        {
                            kase = 3;
                        }
                        else if (ks == p - 1)
                        {
                            kase = 1;
                        }
                        else
                        {
                            kase = 2;
                            k    = ks;
                        }
                    }

                    k++;

                    // Perform the task indicated by kase.
                    switch (kase)
                    {
                    // Deflate negligible s(p).
                    case 1:
                    {
                        Single f = e[p - 2];
                        e[p - 2] = 0;
                        for (int j = p - 2; j >= k; j--)
                        {
                            Single t  = Accord.Math.Tools.Hypotenuse(s[j], f);
                            Single cs = s[j] / t;
                            Single sn = f / t;
                            s[j] = t;
                            if (j != k)
                            {
                                f        = -sn * e[j - 1];
                                e[j - 1] = cs * e[j - 1];
                            }

                            if (wantv)
                            {
                                for (int i = 0; i < n; i++)
                                {
                                    t           = cs * v[i, j] + sn * v[i, p - 1];
                                    v[i, p - 1] = -sn * v[i, j] + cs * v[i, p - 1];
                                    v[i, j]     = t;
                                }
                            }
                        }
                    }
                    break;

                    // Split at negligible s(k).
                    case 2:
                    {
                        Single f = e[k - 1];
                        e[k - 1] = 0;
                        for (int j = k; j < p; j++)
                        {
                            Single t  = Accord.Math.Tools.Hypotenuse(s[j], f);
                            Single cs = s[j] / t;
                            Single sn = f / t;
                            s[j] = t;
                            f    = -sn * e[j];
                            e[j] = cs * e[j];

                            if (wantu)
                            {
                                for (int i = 0; i < m; i++)
                                {
                                    t           = cs * u[i, j] + sn * u[i, k - 1];
                                    u[i, k - 1] = -sn * u[i, j] + cs * u[i, k - 1];
                                    u[i, j]     = t;
                                }
                            }
                        }
                    }
                    break;

                    // Perform one qr step.
                    case 3:
                    {
                        // Calculate the shift.
                        Single scale = System.Math.Max(System.Math.Max(System.Math.Max(System.Math.Max(System.Math.Abs(s[p - 1]), System.Math.Abs(s[p - 2])), System.Math.Abs(e[p - 2])), System.Math.Abs(s[k])), System.Math.Abs(e[k]));
                        Single sp    = s[p - 1] / scale;
                        Single spm1  = s[p - 2] / scale;
                        Single epm1  = e[p - 2] / scale;
                        Single sk    = s[k] / scale;
                        Single ek    = e[k] / scale;
                        Single b     = ((spm1 + sp) * (spm1 - sp) + epm1 * epm1) / 2;
                        Single c     = (sp * epm1) * (sp * epm1);
                        double shift = 0;

                        if ((b != 0) | (c != 0))
                        {
                            if (b < 0)
                            {
                                shift = -System.Math.Sqrt(b * b + c);
                            }
                            else
                            {
                                shift = System.Math.Sqrt(b * b + c);
                            }

                            shift = c / (b + shift);
                        }

                        Single f = (sk + sp) * (sk - sp) + (Single)shift;
                        Single g = sk * ek;

                        // Chase zeros.
                        for (int j = k; j < p - 1; j++)
                        {
                            Single t  = Accord.Math.Tools.Hypotenuse(f, g);
                            Single cs = f / t;
                            Single sn = g / t;
                            if (j != k)
                            {
                                e[j - 1] = t;
                            }
                            f        = cs * s[j] + sn * e[j];
                            e[j]     = cs * e[j] - sn * s[j];
                            g        = sn * s[j + 1];
                            s[j + 1] = cs * s[j + 1];

                            if (wantv)
                            {
                                unsafe
                                {
                                    fixed(Single *ptr_vj = &v[0, j])
                                    {
                                        Single *vj  = ptr_vj;
                                        Single *vj1 = ptr_vj + 1;

                                        for (int i = 0; i < n; i++)
                                        {
                                            /*t = cs * v[i, j] + sn * v[i, j + 1];
                                             * v[i, j + 1] = -sn * v[i, j] + cs * v[i, j + 1];
                                             * v[i, j] = t;*/

                                            Single vij  = *vj;
                                            Single vij1 = *vj1;

                                            t = cs * vij + sn * vij1;
                                            *vj1 = -sn * vij + cs * vij1;
                                            *vj  = t;

                                            vj += n; vj1 += n;
                                        }
                                    }
                                }
                            }

                            t        = Accord.Math.Tools.Hypotenuse(f, g);
                            cs       = f / t;
                            sn       = g / t;
                            s[j]     = t;
                            f        = cs * e[j] + sn * s[j + 1];
                            s[j + 1] = -sn * e[j] + cs * s[j + 1];
                            g        = sn * e[j + 1];
                            e[j + 1] = cs * e[j + 1];

                            if (wantu && (j < m - 1))
                            {
                                fixed(Single *ptr_uj = &u[0, j])
                                {
                                    Single *uj  = ptr_uj;
                                    Single *uj1 = ptr_uj + 1;

                                    for (int i = 0; i < m; i++)
                                    {
                                        /* t = cs * u[i, j] + sn * u[i, j + 1];
                                         * u[i, j + 1] = -sn * u[i, j] + cs * u[i, j + 1];
                                         * u[i, j] = t;*/

                                        Single uij  = *uj;
                                        Single uij1 = *uj1;

                                        t = cs * uij + sn * uij1;
                                        *uj1 = -sn * uij + cs * uij1;
                                        *uj  = t;

                                        uj += nu; uj1 += nu;
                                    }
                                }
                            }
                        }

                        e[p - 2] = f;
                        iter     = iter + 1;
                    }
                    break;

                    // Convergence.
                    case 4:
                    {
                        // Make the singular values positive.
                        if (s[k] <= 0)
                        {
                            s[k] = (s[k] < 0 ? -s[k] : 0);
                            if (wantv)
                            {
                                for (int i = 0; i <= pp; i++)
                                {
                                    v[i, k] = -v[i, k];
                                }
                            }
                        }

                        // Order the singular values.
                        while (k < pp)
                        {
                            if (s[k] >= s[k + 1])
                            {
                                break;
                            }

                            Single t = s[k];
                            s[k]     = s[k + 1];
                            s[k + 1] = t;

                            int ti = si[k];
                            si[k]     = si[k + 1];
                            si[k + 1] = ti;

                            if (wantv && (k < n - 1))
                            {
                                for (int i = 0; i < n; i++)
                                {
                                    t           = v[i, k + 1];
                                    v[i, k + 1] = v[i, k];
                                    v[i, k]     = t;
                                }
                            }

                            if (wantu && (k < m - 1))
                            {
                                for (int i = 0; i < m; i++)
                                {
                                    t           = u[i, k + 1];
                                    u[i, k + 1] = u[i, k];
                                    u[i, k]     = t;
                                }
                            }

                            k++;
                        }

                        iter = 0;
                        p--;
                    }
                    break;
                    }
                }
            }

            // If we are violating JAMA's assumption about
            // the input dimension, we need to swap u and v.
            if (swapped)
            {
                Single[,] temp = this.u;
                this.u         = this.v;
                this.v         = temp;
            }
        }
예제 #24
0
        private void vLoadPlotView()
        {
            tableLayoutPanelLogging.Controls.Remove(mclsPlotLogging);

            if (maau32LogData.GetLength(1) != mastActiveMeasureIndices.Length)
            {
                ResizeArray(ref maau32LogData, 65536, mastActiveMeasureIndices.Length);
            }

            if (maafMinMaxLogData.GetLength(0) != mastActiveMeasureIndices.Length)
            {
                ResizeArray(ref maafMinMaxLogData, mastActiveMeasureIndices.Length, 2);
            }

            seriesdata = new LineSeries[mastActiveMeasureIndices.Length];
            mastYAxes  = new LinearAxis[mastActiveMeasureIndices.Length];

            mclsPlotLogging                      = new OxyPlot.WindowsForms.PlotView();
            mclsPlotLogging.Dock                 = System.Windows.Forms.DockStyle.Fill;
            mclsPlotLogging.Location             = new System.Drawing.Point(0, 0);
            mclsPlotLogging.Margin               = new System.Windows.Forms.Padding(0);
            mclsPlotLogging.Name                 = "plot1";
            mclsPlotLogging.PanCursor            = System.Windows.Forms.Cursors.Hand;
            mclsPlotLogging.Size                 = new System.Drawing.Size(632, 446);
            mclsPlotLogging.TabIndex             = 0;
            mclsPlotLogging.ZoomHorizontalCursor = System.Windows.Forms.Cursors.SizeWE;
            mclsPlotLogging.ZoomRectangleCursor  = System.Windows.Forms.Cursors.SizeNWSE;
            mclsPlotLogging.ZoomVerticalCursor   = System.Windows.Forms.Cursors.SizeNS;

            miZoomForwardIDX = 6;
            miZoomBackIDX    = 6;
            miZoomForward    = maiZoom[miZoomForwardIDX];
            miZoomBack       = maiZoom[miZoomBackIDX];

            for (int iSeriesIDX = 0; iSeriesIDX < mastActiveMeasureIndices.Length; iSeriesIDX++)
            {
                seriesdata[iSeriesIDX] = new LineSeries();
                seriesdata[iSeriesIDX].Points.Add(new DataPoint(0, 0));
                seriesdata[iSeriesIDX].Color = maenLogColours[iSeriesIDX];

                Single fMax;
                Single fMin;
                string szVarName;
                string szUnits;

                fMax      = tclsASAM.mailstActiveMeasLists[miFormIDX][mastActiveMeasureIndices[iSeriesIDX].iMeasureQueueIDX].sUpperLim;
                fMin      = tclsASAM.mailstActiveMeasLists[miFormIDX][mastActiveMeasureIndices[iSeriesIDX].iMeasureQueueIDX].sLowerLim;
                szVarName = tclsASAM.mailstActiveMeasLists[miFormIDX][mastActiveMeasureIndices[iSeriesIDX].iMeasureQueueIDX].szMeasurementName;
                szUnits   = tclsASAM.milstCompuMethodList[maiMeasCompuMethodIndices[iSeriesIDX]].szUnitsString;

                mastYAxes[iSeriesIDX]           = pstCreateNewYAxis(iSeriesIDX, fMax, 0, szVarName, szUnits, maenLogColours[iSeriesIDX]);
                seriesdata[iSeriesIDX].YAxisKey = "YAxis" + iSeriesIDX.ToString();

                maafMinMaxLogData[iSeriesIDX, 0] = tclsASAM.mailstActiveMeasLists[miFormIDX][mastActiveMeasureIndices[iSeriesIDX].iMeasureQueueIDX].sUpperLim;
            }

            mclsPlotModel = new PlotModel
            {
                PlotType   = PlotType.Cartesian,
                Background = OxyColors.Black,
                TextColor  = OxyColors.Aqua
            };

            mstXAxis = new OxyPlot.Axes.LinearAxis()
            {
                Position           = OxyPlot.Axes.AxisPosition.Bottom,
                AbsoluteMaximum    = 3600000,
                AbsoluteMinimum    = 0,
                MinorStep          = 5,
                Unit               = "s",
                TicklineColor      = OxyColors.Aqua,
                TitleColor         = OxyColors.Aqua,
                AxislineColor      = OxyColors.Aqua,
                ExtraGridlineColor = OxyColors.Aqua,
                MajorGridlineColor = OxyColors.Aqua,
                TitleFontWeight    = FontWeights.Bold
            };

            mstXAxis.Zoom(0f, 30f);
            mclsPlotModel.Axes.Add(mstXAxis);

            for (int iSeriesIDX = 0; iSeriesIDX < mastActiveMeasureIndices.Length; iSeriesIDX++)
            {
                if (iSeriesIDX != miTimeStampIDX)
                {
                    mclsPlotModel.Series.Add(seriesdata[iSeriesIDX]);
                    mclsPlotModel.Axes.Add(mastYAxes[iSeriesIDX]);
                }
            }

            mclsPlotLogging.Model = mclsPlotModel;
            miLoggingIDX          = 1;

            tableLayoutPanelLogging.Controls.Add(mclsPlotLogging, 0, 1);
            tableLayoutPanelLogging.SetColumnSpan(mclsPlotLogging, 9);
            tableLayoutPanelLogging.SetRowSpan(mclsPlotLogging, 1);

            LoadComboBoxLoggingVars();
        }