public void ConstructorException2()
 {
     MatrixF m = new MatrixF(new float[,] {{ 1, 2 },
                                    { 3, 4 },
                                    { 5, 6 }});
       new EigenvalueDecompositionF(m);
 }
Ejemplo n.º 2
0
        public void DeterminantException()
        {
            MatrixF a = new MatrixF(new float[,] { { 1, 2 }, { 5, 6 }, { 0, 1 } });

              LUDecompositionF d = new LUDecompositionF(a);
              float det = d.Determinant;
        }
        public void Test1()
        {
            MatrixF a = new MatrixF(new float[,] { { 2, -1, 0},
                                             { -1, 2, -1},
                                             { 0, -1, 2} });

              CholeskyDecompositionF d = new CholeskyDecompositionF(a);

              Assert.AreEqual(true, d.IsSymmetricPositiveDefinite);

              MatrixF l = d.L;

              Assert.AreEqual(0, l[0, 1]);
              Assert.AreEqual(0, l[0, 2]);
              Assert.AreEqual(0, l[1, 2]);

              Assert.IsTrue(MatrixF.AreNumericallyEqual(a, l * l.Transposed));

              Assert.IsTrue(MatrixF.AreNumericallyEqual(a, l * l.Transposed));

              // Check solving of linear equations.
              MatrixF x = new MatrixF(new float[,] { { 1, 2},
                                             { 3, 4},
                                             { 5, 6} });
              MatrixF b = a * x;

              Assert.IsTrue(MatrixF.AreNumericallyEqual(x, d.SolveLinearEquations(b)));
        }
Ejemplo n.º 4
0
        public void TestRandomA()
        {
            RandomHelper.Random = new Random(1);

              for (int i = 0; i < 100; i++)
              {
            // Create A.
            MatrixF a = new MatrixF(3, 3);
            RandomHelper.Random.NextMatrixF(a, 0, 1);

            LUDecompositionF d = new LUDecompositionF(a);

            if (d.IsNumericallySingular == false)
            {
              // Check solving of linear equations.
              MatrixF b = new MatrixF(3, 2);
              RandomHelper.Random.NextMatrixF(b, 0, 1);

              MatrixF x = d.SolveLinearEquations(b);
              MatrixF b2 = a * x;
              Assert.IsTrue(MatrixF.AreNumericallyEqual(b, b2, 0.01f));

              MatrixF aPermuted = d.L * d.U;
              Assert.IsTrue(MatrixF.AreNumericallyEqual(aPermuted, a.GetSubmatrix(d.PivotPermutationVector, 0, 2)));
            }
              }
        }
        public void TestMatricesWithoutFullRank()
        {
            MatrixF a = new MatrixF(3, 3);
              SingularValueDecompositionF svd = new SingularValueDecompositionF(a);
              Assert.AreEqual(0, svd.NumericalRank);
              Assert.AreEqual(svd.SingularValues[0], svd.Norm2);
              float condNumber = svd.ConditionNumber;

              a = new MatrixF(new float[,] { { 1, 2, 3 }, { 4, 5, 6 }, { 4, 5, 6 } });
              svd = new SingularValueDecompositionF(a);
              Assert.AreEqual(2, svd.NumericalRank);
              Assert.AreEqual(svd.SingularValues[0], svd.Norm2);
              Assert.IsTrue(MatrixF.AreNumericallyEqual(a, svd.U * svd.S * svd.V.Transposed));
              svd = new SingularValueDecompositionF(a.Transposed);
              Assert.AreEqual(2, svd.NumericalRank);
              Assert.IsTrue(MatrixF.AreNumericallyEqual(a.Transposed, svd.U * svd.S * svd.V.Transposed));
              Assert.IsTrue(MatrixF.AreNumericallyEqual(a.Transposed, svd.U * svd.S * svd.V.Transposed)); // Repeat to test with cached values.
              Assert.AreEqual(svd.SingularValues[0], svd.Norm2);
              condNumber = svd.ConditionNumber;

              a = new MatrixF(new float[,] { { 1, 2 }, { 1, 2 }, { 1, 2 } });
              svd = new SingularValueDecompositionF(a);
              Assert.AreEqual(1, svd.NumericalRank);
              Assert.IsTrue(MatrixF.AreNumericallyEqual(a, svd.U * svd.S * svd.V.Transposed));
              Assert.AreEqual(svd.SingularValues[0], svd.Norm2);
              condNumber = svd.ConditionNumber;
        }
        //--------------------------------------------------------------
        /// <summary>
        /// Creates the principal component analysis for the given list of points.
        /// </summary>
        /// <param name="points">
        /// The list of data points. All points must have the same 
        /// <see cref="VectorF.NumberOfElements"/>.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="points"/> is <see langword="null"/>.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// <paramref name="points"/> is empty.
        /// </exception>
        public PrincipalComponentAnalysisF(IList<VectorF> points)
        {
            if (points == null)
            throw new ArgumentNullException("points");
              if (points.Count == 0)
            throw new ArgumentException("The list of points is empty.");

              // Compute covariance matrix.
              MatrixF covarianceMatrix = StatisticsHelper.ComputeCovarianceMatrix(points);

              // Perform Eigenvalue decomposition.
              EigenvalueDecompositionF evd = new EigenvalueDecompositionF(covarianceMatrix);

              int numberOfElements = evd.RealEigenvalues.NumberOfElements;
              Variances = new VectorF(numberOfElements);
              V = new MatrixF(numberOfElements, numberOfElements);

              // Sort eigenvalues by decreasing value.
              // Since covarianceMatrix is symmetric, we have no imaginary eigenvalues.
              for (int i = 0; i < Variances.NumberOfElements; i++)
              {
            int index = evd.RealEigenvalues.IndexOfLargestElement;

            Variances[i] = evd.RealEigenvalues[index];
            V.SetColumn(i, evd.V.GetColumn(index));

            evd.RealEigenvalues[index] = float.NegativeInfinity;
              }
        }
        public void SolveLinearEquationsException1()
        {
            // Create A.
              MatrixF a = new MatrixF(new float[,] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, -9 } });

              CholeskyDecompositionF decomp = new CholeskyDecompositionF(a);
              decomp.SolveLinearEquations(null);
        }
Ejemplo n.º 8
0
 public void AddMatrix()
 {
     MatrixF m1 = new MatrixF(3, 4, rowMajor, MatrixOrder.RowMajor);
       MatrixF m2 = new MatrixF(3, 4, rowMajor, MatrixOrder.RowMajor) * (-3);
       MatrixF result = MatrixF.Add(m1, m2);
       for (int i = 0; i < 12; i++)
     Assert.AreEqual(-rowMajor[i] * 2, result[i]);
 }
        public void Test2()
        {
            MatrixF a = new MatrixF(new float[,] {{ 0, 1, 2 },
                                           { 1, 4, 3 },
                                           { 2, 3, 5}});
              EigenvalueDecompositionF d = new EigenvalueDecompositionF(a);

              Assert.IsTrue(MatrixF.AreNumericallyEqual(a, d.V * d.D * d.V.Transposed));
        }
        public void Test1()
        {
            MatrixF a = new MatrixF(new float[,] {{ 1, -1, 4 },
                                           { 3, 2, -1 },
                                           { 2, 1, -1}});
              EigenvalueDecompositionF d = new EigenvalueDecompositionF(a);

              Assert.IsTrue(MatrixF.AreNumericallyEqual(a * d.V, d.V * d.D));
        }
Ejemplo n.º 11
0
        public void SolveLinearEquationsException3()
        {
            // Create A.
              MatrixF a = new MatrixF(new float[,] { { 1, 2, 3 }, { 4, 5, 6 }, { 1, 2, 3 } });
              MatrixF b = new MatrixF(new float[,] { { 1, 2, 3 }, { 4, 5, 6 }, {7, 8, -9 } });

              QRDecompositionF decomp = new QRDecompositionF(a);
              decomp.SolveLinearEquations(b);
        }
Ejemplo n.º 12
0
        //--------------------------------------------------------------
        /// <summary>
        /// Creates the eigenvalue decomposition of the given matrix.
        /// </summary>
        /// <param name="matrixA">The square matrix A.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="matrixA"/> is <see langword="null"/>.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// <paramref name="matrixA"/> is non-square (rectangular).
        /// </exception>
        public EigenvalueDecompositionF(MatrixF matrixA)
        {
            if (matrixA == null)
            throw new ArgumentNullException("matrixA");
              if (matrixA.IsSquare == false)
            throw new ArgumentException("The matrix A must be square.", "matrixA");

              _n = matrixA.NumberOfColumns;
              _d = new VectorF(_n);
              _e = new VectorF(_n);

              _isSymmetric = matrixA.IsSymmetric;

              if (_isSymmetric)
              {
            _v = matrixA.Clone();

            // Tridiagonalize.
            ReduceToTridiagonal();

            // Diagonalize.
            TridiagonalToQL();
              }
              else
              {
            _v = new MatrixF(_n, _n);

            // Abort if A contains NaN values.
            // If we continue with NaN values, we run into an infinite loop.
            for (int i = 0; i < _n; i++)
            {
              for (int j = 0; j < _n; j++)
              {
            if (Numeric.IsNaN(matrixA[i, j]))
            {
              _e.Set(float.NaN);
              _v.Set(float.NaN);
              _d.Set(float.NaN);
              return;
            }
              }
            }

            // Storage of nonsymmetric Hessenberg form.
            MatrixF matrixH = matrixA.Clone();
            // Working storage for nonsymmetric algorithm.
            float[] ort = new float[_n];

            // Reduce to Hessenberg form.
            ReduceToHessenberg(matrixH, ort);

            // Reduce Hessenberg to real Schur form.
            HessenbergToRealSchur(matrixH);
              }
        }
Ejemplo n.º 13
0
        public void Test1()
        {
            MatrixF A = new MatrixF(new float[,] { { 4 } });
              VectorF b = new VectorF(new float[] { 20 });

              SorMethodF solver = new SorMethodF();
              VectorF x = solver.Solve(A, null, b);

              Assert.IsTrue(VectorF.AreNumericallyEqual(new VectorF(1, 5), x));
              Assert.AreEqual(2, solver.NumberOfIterations);
        }
Ejemplo n.º 14
0
        public void Determinant()
        {
            MatrixF a = new MatrixF(new float[,] { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 0, 1, 2, 0 }, { 1, 0, 1, 0 } });

              LUDecompositionF d = new LUDecompositionF(a);
              Assert.AreEqual(false, d.IsNumericallySingular);
              Assert.IsTrue(Numeric.AreEqual(-24, d.Determinant));

              MatrixF aPermuted = d.L * d.U;
              Assert.IsTrue(MatrixF.AreNumericallyEqual(aPermuted, a.GetSubmatrix(d.PivotPermutationVector, 0, 3)));
        }
Ejemplo n.º 15
0
        public void SolveWithDefaultInitialGuess()
        {
            MatrixF A = new MatrixF(new float[,] { { 4 } });
              VectorF b = new VectorF(new float[] { 20 });

              JacobiMethodF solver = new JacobiMethodF();
              VectorF x = solver.Solve(A, b);

              Assert.IsTrue(VectorF.AreNumericallyEqual(new VectorF(1, 5), x));
              Assert.AreEqual(2, solver.NumberOfIterations);
        }
Ejemplo n.º 16
0
        public void Test2()
        {
            MatrixF A = new MatrixF(new float[,] { { 1, 0 },
                                             { 0, 1 }});
              VectorF b = new VectorF(new float[] { 20, 28 });

              JacobiMethodF solver = new JacobiMethodF();
              VectorF x = solver.Solve(A, null, b);

              Assert.IsTrue(VectorF.AreNumericallyEqual(b, x));
              Assert.AreEqual(2, solver.NumberOfIterations);
        }
Ejemplo n.º 17
0
        public void Test4()
        {
            MatrixF A = new MatrixF(new float[,] { { -12, 2 },
                                             { 2, 3 }});
              VectorF b = new VectorF(new float[] { 20, 28 });

              SorMethodF solver = new SorMethodF();
              VectorF x = solver.Solve(A, null, b);

              VectorF solution = MatrixF.SolveLinearEquations(A, b);
              Assert.IsTrue(VectorF.AreNumericallyEqual(solution, x));
        }
Ejemplo n.º 18
0
        public void Test3()
        {
            MatrixF A = new MatrixF(new float[,] { { 2, 0 },
                                             { 0, 2 }});
              VectorF b = new VectorF(new float[] { 20, 28 });

              GaussSeidelMethodF solver = new GaussSeidelMethodF();
              VectorF x = solver.Solve(A, null, b);

              Assert.IsTrue(VectorF.AreNumericallyEqual(b / 2, x));
              Assert.AreEqual(2, solver.NumberOfIterations);
        }
        public void SolveLinearEquationsException3()
        {
            // Create A.
            MatrixF a = new MatrixF(new float[, ] {
                { 1, 2, 3 }, { 4, 5, 6 }, { 1, 2, 3 }
            });
            MatrixF b = new MatrixF(new float[, ] {
                { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, -9 }
            });

            CholeskyDecompositionF decomp = new CholeskyDecompositionF(a);

            decomp.SolveLinearEquations(b);
        }
Ejemplo n.º 20
0
        public void Test3()
        {
            MatrixF A = new MatrixF(new float[, ] {
                { 2, 0 },
                { 0, 2 }
            });
            VectorF b = new VectorF(new float[] { 20, 28 });

            GaussSeidelMethodF solver = new GaussSeidelMethodF();
            VectorF            x      = solver.Solve(A, null, b);

            Assert.IsTrue(VectorF.AreNumericallyEqual(b / 2, x));
            Assert.AreEqual(2, solver.NumberOfIterations);
        }
Ejemplo n.º 21
0
        public void Test2()
        {
            MatrixF A = new MatrixF(new float[, ] {
                { 1, 0 },
                { 0, 1 }
            });
            VectorF b = new VectorF(new float[] { 20, 28 });

            JacobiMethodF solver = new JacobiMethodF();
            VectorF       x      = solver.Solve(A, null, b);

            Assert.IsTrue(VectorF.AreNumericallyEqual(b, x));
            Assert.AreEqual(2, solver.NumberOfIterations);
        }
Ejemplo n.º 22
0
        public void Test5()
        {
            MatrixF A = new MatrixF(new float[,] { { -21, 2, -4, 0 },
                                             { 2, 3, 0.1f, -1 },
                                             { 2, 10, 111.1f, -11 },
                                             { 23, 112, 111.1f, -143 }});
              VectorF b = new VectorF(new float[] { 20, 28, -12, 0.1f });

              GaussSeidelMethodF solver = new GaussSeidelMethodF();
              VectorF x = solver.Solve(A, null, b);

              VectorF solution = MatrixF.SolveLinearEquations(A, b);
              Assert.IsTrue(VectorF.AreNumericallyEqual(solution, x));
        }
Ejemplo n.º 23
0
        public void Determinant()
        {
            MatrixF a = new MatrixF(new float[, ] {
                { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 0, 1, 2, 0 }, { 1, 0, 1, 0 }
            });

            LUDecompositionF d = new LUDecompositionF(a);

            Assert.AreEqual(false, d.IsNumericallySingular);
            Assert.IsTrue(Numeric.AreEqual(-24, d.Determinant()));

            MatrixF aPermuted = d.L * d.U;

            Assert.IsTrue(MatrixF.AreNumericallyEqual(aPermuted, a.GetSubmatrix(d.PivotPermutationVector, 0, 3)));
        }
Ejemplo n.º 24
0
        public void Test4()
        {
            MatrixF A = new MatrixF(new float[, ] {
                { -12, 2 },
                { 2, 3 }
            });
            VectorF b = new VectorF(new float[] { 20, 28 });

            SorMethodF solver = new SorMethodF();
            VectorF    x      = solver.Solve(A, null, b);

            VectorF solution = MatrixF.SolveLinearEquations(A, b);

            Assert.IsTrue(VectorF.AreNumericallyEqual(solution, x));
        }
Ejemplo n.º 25
0
        public static void NextMatrixF(this Random random, MatrixF matrix, float min, float max)
        {
            if (random == null)
            {
                random = Random;
            }

            for (int r = 0; r < matrix.NumberOfRows; r++)
            {
                for (int c = 0; c < matrix.NumberOfColumns; c++)
                {
                    matrix[r, c] = NextFloat(random, min, max);
                }
            }
        }
        /// <summary>
        /// Creates the Cholesky decomposition of the given matrix.
        /// </summary>
        /// <param name="matrixA">The square matrix A.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="matrixA"/> is <see langword="null"/>.
        /// </exception>
        public CholeskyDecompositionF(MatrixF matrixA)
        {
            // Note: A different algorithm can be found in the Numerical Recipes book.

            if (matrixA == null)
            {
                throw new ArgumentNullException("matrixA");
            }

            int n = matrixA.NumberOfRows;

            _isSymmetricPositiveDefinite = true;

            // Is matrix square?
            if (matrixA.NumberOfColumns != n)
            {
                // Not square!
                n = Math.Min(n, matrixA.NumberOfColumns);
                _isSymmetricPositiveDefinite = false;
            }

            _l = new MatrixF(n, n);

            for (int j = 0; j < n; j++)
            {
                float d = 0;
                for (int k = 0; k < j; k++)
                {
                    float s = 0;

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

                    s       = (matrixA[j, k] - s) / _l[k, k];
                    L[j, k] = s;
                    d       = d + s * s;
                    _isSymmetricPositiveDefinite = _isSymmetricPositiveDefinite && (matrixA[k, j] == matrixA[j, k]);
                }

                d = matrixA[j, j] - d;
                _isSymmetricPositiveDefinite = _isSymmetricPositiveDefinite && (d > 0);
                _l[j, j] = (float)Math.Sqrt(Math.Max(d, 0));
                //for (int k = j + 1; k < n; k++)
                //  _l[j, k] = 0;      // Not needed. Already initialized with 0.
            }
        }
Ejemplo n.º 27
0
        /// <summary>
        /// Solves the specified linear system of equations <i>Ax=b</i>.
        /// </summary>
        /// <param name="matrixA">The matrix A.</param>
        /// <param name="initialX">
        /// The initial guess for x. If this value is <see langword="null"/>, a zero vector will be used
        /// as initial guess.
        /// </param>
        /// <param name="vectorB">The vector b.</param>
        /// <returns>The solution vector x.</returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="matrixA"/> is <see langword="null"/>.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="vectorB"/> is <see langword="null"/>.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// <paramref name="matrixA"/> is not a square matrix.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// The number of elements of <paramref name="initialX"/> does not match.
        /// </exception>
        public override VectorF Solve(MatrixF matrixA, VectorF initialX, VectorF vectorB)
        {
            // TODO: We can possible improve the method by reordering after each step.
              // This can be done randomly or we sort by the "convergence" of the elements.
              // See book Physics-Based Animation.

              NumberOfIterations = 0;

              if (matrixA == null)
            throw new ArgumentNullException("matrixA");
              if (vectorB == null)
            throw new ArgumentNullException("vectorB");
              if (matrixA.IsSquare == false)
            throw new ArgumentException("Matrix A must be a square matrix.", "matrixA");
              if (matrixA.NumberOfRows != vectorB.NumberOfElements)
            throw new ArgumentException("The number of rows of A and b do not match.");
              if (initialX != null && initialX.NumberOfElements != vectorB.NumberOfElements)
            throw new ArgumentException("The number of elements of the initial guess for x and b do not match.");

              VectorF xOld = initialX ?? new VectorF(vectorB.NumberOfElements);
              VectorF xNew = new VectorF(vectorB.NumberOfElements);
              bool isConverged = false;

              // Make iterations until max iteration count or the result has converged.
              for (int i = 0; i < MaxNumberOfIterations && !isConverged; i++)
              {
            for (int j = 0; j < vectorB.NumberOfElements; j++)
            {
              float delta = 0;
              for (int k = 0; k < j; k++)
            delta += matrixA[j, k] * xOld[k];

              for (int k = j + 1; k < vectorB.NumberOfElements; k++)
            delta += matrixA[j, k] * xOld[k];

              xNew[j] = (vectorB[j] - delta) / matrixA[j, j];
            }

            // Test convergence
            isConverged = VectorF.AreNumericallyEqual(xOld, xNew, Epsilon);

            xOld = xNew.Clone();
            NumberOfIterations = i + 1;
              }

              return xNew;
        }
Ejemplo n.º 28
0
        //--------------------------------------------------------------
        #region Methods
        //--------------------------------------------------------------

        /// <summary>
        /// Solves the equation <c>A * X = B</c>.
        /// </summary>
        /// <param name="matrixB">The matrix B with as many rows as A and any number of columns.</param>
        /// <returns>X, so that <c>A * X = B</c>.</returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="matrixB"/> is <see langword="null"/>.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// The number of rows does not match.
        /// </exception>
        /// <exception cref="MathematicsException">
        /// The matrix A is numerically singular.
        /// </exception>
        public MatrixF SolveLinearEquations(MatrixF matrixB)
        {
            if (matrixB == null)
            {
                throw new ArgumentNullException("matrixB");
            }
            if (matrixB.NumberOfRows != _m)
            {
                throw new ArgumentException("The number of rows does not match.", "matrixB");
            }
            if (IsNumericallySingular)
            {
                throw new MathematicsException("The original matrix A is numerically singular.");
            }

            // Copy right hand side with pivoting
            MatrixF x = matrixB.GetSubmatrix(_pivotVector, 0, matrixB.NumberOfColumns - 1);

            // Solve L*Y = B(piv,:)
            for (int k = 0; k < _n; k++)
            {
                for (int i = k + 1; i < _n; i++)
                {
                    for (int j = 0; j < matrixB.NumberOfColumns; j++)
                    {
                        x[i, j] -= x[k, j] * _lu[i, k];
                    }
                }
            }

            // Solve U*X = Y;
            for (int k = _n - 1; k >= 0; k--)
            {
                for (int j = 0; j < matrixB.NumberOfColumns; j++)
                {
                    x[k, j] /= _lu[k, k];
                }
                for (int i = 0; i < k; i++)
                {
                    for (int j = 0; j < matrixB.NumberOfColumns; j++)
                    {
                        x[i, j] -= x[k, j] * _lu[i, k];
                    }
                }
            }
            return(x);
        }
Ejemplo n.º 29
0
        public void TestRandomRegularA()
        {
            RandomHelper.Random = new Random(1);

            for (int i = 0; i < 100; i++)
            {
                VectorF column1 = new VectorF(3);
                RandomHelper.Random.NextVectorF(column1, 1, 2);

                VectorF column2 = new VectorF(3);
                RandomHelper.Random.NextVectorF(column2, 1, 2);

                // Make linearly independent.
                if (column1 / column1[0] == column2 / column2[0])
                {
                    column2[0]++;
                }

                // Create linearly independent third column.
                VectorF column3 = column1 + column2;
                column3[1]++;

                // Create A.
                MatrixF a = new MatrixF(3, 3);
                a.SetColumn(0, column1);
                a.SetColumn(1, column2);
                a.SetColumn(2, column3);

                LUDecompositionF d = new LUDecompositionF(a);

                MatrixF aPermuted = d.L * d.U;
                Assert.IsTrue(MatrixF.AreNumericallyEqual(aPermuted, a.GetSubmatrix(d.PivotPermutationVector, 0, 2)));
                aPermuted = d.L * d.U; // Repeat with to test cached values.
                Assert.IsTrue(MatrixF.AreNumericallyEqual(aPermuted, a.GetSubmatrix(d.PivotPermutationVector, 0, 2)));

                Assert.AreEqual(false, d.IsNumericallySingular);

                // Check solving of linear equations.
                MatrixF b = new MatrixF(3, 2);
                RandomHelper.Random.NextMatrixF(b, 0, 1);

                MatrixF x  = d.SolveLinearEquations(b);
                MatrixF b2 = a * x;
                Assert.IsTrue(MatrixF.AreNumericallyEqual(b, b2, 0.01f));
            }
        }
Ejemplo n.º 30
0
        public void TestMatricesWithFullRank()
        {
            MatrixF a = new MatrixF(new float[,] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, -9 } });
              QRDecompositionF qr = new QRDecompositionF(a);
              Assert.AreEqual(true, qr.HasNumericallyFullRank);
              Assert.IsTrue(MatrixF.AreNumericallyEqual(a, qr.Q * qr.R));
              qr = new QRDecompositionF(a.Transposed);
              Assert.AreEqual(true, qr.HasNumericallyFullRank);
              Assert.IsTrue(MatrixF.AreNumericallyEqual(a.Transposed, qr.Q * qr.R));

              a = new MatrixF(new float[,] { { 1, 2 }, { 4, 5 }, { 4, 5 } });
              qr = new QRDecompositionF(a);
              Assert.AreEqual(true, qr.HasNumericallyFullRank);
              Assert.IsTrue(MatrixF.AreNumericallyEqual(a, qr.Q * qr.R));

              MatrixF h = qr.H;  // Just call this one to see if it runs through.
        }
Ejemplo n.º 31
0
        public void Test5()
        {
            MatrixF A = new MatrixF(new float[, ] {
                { -21, 2, -4, 0 },
                { 2, 3, 0.1f, -1 },
                { 2, 10, 111.1f, -11 },
                { 23, 112, 111.1f, -143 }
            });
            VectorF b = new VectorF(new float[] { 20, 28, -12, 0.1f });

            SorMethodF solver = new SorMethodF();
            VectorF    x      = solver.Solve(A, null, b);

            VectorF solution = MatrixF.SolveLinearEquations(A, b);

            Assert.IsTrue(VectorF.AreNumericallyEqual(solution, x));
        }
        /// <summary>
        /// Solves the equation <c>A * X = B</c>.
        /// </summary>
        /// <param name="matrixB">The matrix B with as many rows as A and any number of columns.</param>
        /// <returns>X, so that <c>A * X = B</c>.</returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="matrixB"/> is <see langword="null"/>.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// The number of rows does not match.
        /// </exception>
        /// <exception cref="MathematicsException">
        /// The matrix A is not symmetric and positive definite.
        /// </exception>
        public MatrixF SolveLinearEquations(MatrixF matrixB)
        {
            if (matrixB == null)
            {
                throw new ArgumentNullException("matrixB");
            }
            if (matrixB.NumberOfRows != L.NumberOfRows)
            {
                throw new ArgumentException("The number of rows does not match.", "matrixB");
            }
            if (IsSymmetricPositiveDefinite == false)
            {
                throw new MathematicsException("The original matrix A is not symmetric and positive definite.");
            }

            // Initialize x as a copy of B.
            MatrixF x = matrixB.Clone();

            // Solve L*Y = B.
            for (int k = 0; k < L.NumberOfRows; k++)
            {
                for (int j = 0; j < matrixB.NumberOfColumns; j++)
                {
                    for (int i = 0; i < k; i++)
                    {
                        x[k, j] -= x[i, j] * L[k, i];
                    }
                    x[k, j] /= L[k, k];
                }
            }

            // Solve transpose(L) * X = Y.
            for (int k = L.NumberOfRows - 1; k >= 0; k--)
            {
                for (int j = 0; j < matrixB.NumberOfColumns; j++)
                {
                    for (int i = k + 1; i < L.NumberOfRows; i++)
                    {
                        x[k, j] -= x[i, j] * L[i, k];
                    }
                    x[k, j] /= L[k, k];
                }
            }
            return(x);
        }
        /// <summary>
        /// Called when <see cref="ScatteredInterpolationF.Setup"/> is called.
        /// </summary>
        /// <remarks>
        /// Here internal values can be computed from the registered reference pairs if required. It is
        /// assured that the reference data pairs have valid dimensions: All x values have the same
        /// number of elements and all y values have the same number of elements. All reference data
        /// values are not <see langword="null"/>.
        /// </remarks>
        /// <exception cref="MathematicsException">
        /// Cannot compute regression - try to choose different reference data pairs or another basis
        /// function.
        /// </exception>
        protected override void OnSetup()
        {
            // Compute weights:
            // Make matrix Φ (also known as G).
            int     numberOfPairs = Count;
            MatrixF G             = new MatrixF(numberOfPairs, numberOfPairs);

            for (int r = 0; r < numberOfPairs; r++)     // rows
            {
                for (int c = 0; c < numberOfPairs; c++) // columns
                {
                    float radialArgument = DistanceFunction(GetX(r), GetX(c), c);
                    G[r, c] = BasisFunction(radialArgument, c);
                }
            }

            // We look for the matrix W that contains the weights.
            // Each row resembles an n-dimensional weight.
            MatrixF W;

            // Make the matrix Y with the reference values, such that ideally Y = G * W.
            MatrixF Y = new MatrixF(numberOfPairs, GetY(0).NumberOfElements);

            for (int r = 0; r < numberOfPairs; r++)
            {
                Y.SetRow(r, GetY(r));
            }

            // Compute W as the least squares solution.
            try
            {
                W = MatrixF.SolveLinearEquations(G, Y);
            }
            catch (MathematicsException exception)
            {
                throw new MathematicsException("Cannot compute regression - try to choose different reference data pairs or another basis function.", exception);
            }

            // The rows of W are the weights.
            _weights = new VectorF[numberOfPairs];
            for (int r = 0; r < numberOfPairs; r++)
            {
                _weights[r] = W.GetRow(r);
            }
        }
Ejemplo n.º 34
0
 public Bone(int boneIndex, int parentIndex, Bone parent, string name,
             CoordinateF defaultPosition, CoordinateF defaultAngles,
             CoordinateF defaultPositionScale, CoordinateF defaultAnglesScale)
 {
     BoneIndex            = boneIndex;
     ParentIndex          = parentIndex;
     Parent               = parent;
     Name                 = name;
     DefaultPosition      = defaultPosition;
     DefaultAngles        = defaultAngles;
     DefaultPositionScale = defaultPositionScale;
     DefaultAnglesScale   = defaultAnglesScale;
     Transform            = QuaternionF.EulerAngles(DefaultAngles).GetMatrix().Translate(defaultPosition);
     if (parent != null)
     {
         Transform *= parent.Transform;
     }
 }
Ejemplo n.º 35
0
        //--------------------------------------------------------------
        /// <summary>
        /// Creates the QR decomposition of the given matrix.
        /// </summary>
        /// <param name="matrixA">
        /// The matrix A. (Can be rectangular. NumberOfRows must be ≥ NumberOfColumns.)
        /// </param>
        /// <remarks>
        /// The QR decomposition is computed by Householder reflections.
        /// </remarks>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="matrixA"/> is <see langword="null"/>.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// The number of rows must be greater than or equal to the number of columns.
        /// </exception>
        public QRDecompositionF(MatrixF matrixA)
        {
            if (matrixA == null)
            throw new ArgumentNullException("matrixA");
              if (matrixA.NumberOfRows < matrixA.NumberOfColumns)
            throw new ArgumentException("The number of rows must be greater than or equal to the number of columns.", "matrixA");

              // Initialize.
              _qr = matrixA.Clone();
              _m = matrixA.NumberOfRows;
              _n = matrixA.NumberOfColumns;
              _rDiagonal = new float[_n];

              // Main loop.
              for (int k = 0; k < _n; k++)
              {
            // Compute 2-norm of k-th column without under/overflow.
            float norm = 0;
            for (int i = k; i < _m; i++)
              norm = MathHelper.Hypotenuse(norm, _qr[i, k]);

            if (norm != 0)   // TODO: Maybe a comparison with an epsilon tolerance is required here!?
            {
              // Form k-th Householder vector.
              if (_qr[k, k] < 0)
            norm = -norm;
              for (int i = k; i < _m; i++)
            _qr[i, k] /= norm;
              _qr[k, k] += 1;

              // Apply transformation to remaining columns.
              for (int j = k + 1; j < _n; j++)
              {
            float s = 0;
            for (int i = k; i < _m; i++)
              s += _qr[i, k] * _qr[i, j];
            s = -s / _qr[k, k];
            for (int i = k; i < _m; i++)
              _qr[i, j] += s * _qr[i, k];
              }
            }
            _rDiagonal[k] = -norm;
              }
        }
Ejemplo n.º 36
0
        public void TestRandomRegularA()
        {
            RandomHelper.Random = new Random(1);

            for (int i = 0; i < 100; i++)
            {
                VectorF column1 = new VectorF(3);
                RandomHelper.Random.NextVectorF(column1, 1, 2);
                VectorF column2 = new VectorF(3);
                RandomHelper.Random.NextVectorF(column2, 1, 2);

                // Make linearly independent.
                if (column1 / column1[0] == column2 / column2[0])
                {
                    column2[0]++;
                }

                // Create linearly independent third column.
                VectorF column3 = column1 + column2;
                column3[1]++;

                // Create A.
                MatrixF a = new MatrixF(3, 3);
                a.SetColumn(0, column1);
                a.SetColumn(1, column2);
                a.SetColumn(2, column3);

                QRDecompositionF d = new QRDecompositionF(a);
                Assert.IsTrue(MatrixF.AreNumericallyEqual(a, d.Q * d.R));
                Assert.IsTrue(MatrixF.AreNumericallyEqual(a, d.Q * d.R)); // Second time with the cached values.
                Assert.AreEqual(true, d.HasNumericallyFullRank);

                // Check solving of linear equations.
                MatrixF b = new MatrixF(3, 2);
                RandomHelper.Random.NextMatrixF(b, 0, 1);

                MatrixF x  = d.SolveLinearEquations(b);
                MatrixF b2 = a * x;
                Assert.IsTrue(MatrixF.AreNumericallyEqual(b, b2, 0.01f));

                MatrixF h = d.H; // Just call this one to see if it runs through.
                h = d.H;         // Call it secont time to cover code with internal caching.
            }
        }
Ejemplo n.º 37
0
        /// <summary>
        /// Creates a new NeuralNetwork based on an instance.
        /// </summary>
        /// <param name="_nn"></param>
        /// <returns></returns>
        public static NeuralNetwork Copy(NeuralNetwork _nn)
        {
            NeuralNetwork nn2 = new NeuralNetwork(
                _nn.inputs, _nn.hiddenNodes, _nn.outputs, _nn.numHiddenLayers);
            List <MatrixF> weights = new List <MatrixF>();
            List <MatrixF> bias    = new List <MatrixF>();

            for (int i = 0; i < _nn.weightMatrixes.Count; i++)
            {
                weights.Add(MatrixF.Copy(_nn.weightMatrixes[i]));
            }
            for (int i = 0; i < _nn.biasMatrixes.Count; i++)
            {
                bias.Add(MatrixF.Copy(_nn.biasMatrixes[i]));
            }
            nn2.weightMatrixes = weights;
            nn2.biasMatrixes   = bias;
            return(nn2);
        }
Ejemplo n.º 38
0
        //--------------------------------------------------------------
        /// <summary>
        /// Creates the Cholesky decomposition of the given matrix.
        /// </summary>
        /// <param name="matrixA">The square matrix A.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="matrixA"/> is <see langword="null"/>.
        /// </exception>
        public CholeskyDecompositionF(MatrixF matrixA)
        {
            // Note: A different algorithm can be found in the Numerical Recipes book.

              if (matrixA == null)
            throw new ArgumentNullException("matrixA");

              int n = matrixA.NumberOfRows;
              _isSymmetricPositiveDefinite = true;

              // Is matrix square?
              if (matrixA.NumberOfColumns != n)
              {
            // Not square!
            n = Math.Min(n, matrixA.NumberOfColumns);
            _isSymmetricPositiveDefinite = false;
              }

              _l = new MatrixF(n, n);

              for (int j = 0; j < n; j++)
              {
            float d = 0;
            for (int k = 0; k < j; k++)
            {
              float s = 0;

              for (int i = 0; i < k; i++)
            s += _l[k, i] * _l[j, i];

              s = (matrixA[j, k] - s) / _l[k, k];
              L[j, k] = s;
              d = d + s * s;
              _isSymmetricPositiveDefinite = _isSymmetricPositiveDefinite && (matrixA[k, j] == matrixA[j, k]);
            }

            d = matrixA[j, j] - d;
            _isSymmetricPositiveDefinite = _isSymmetricPositiveDefinite && (d > 0);
            _l[j, j] = (float) Math.Sqrt(Math.Max(d, 0));
            //for (int k = j + 1; k < n; k++)
            //  _l[j, k] = 0;      // Not needed. Already initialized with 0.
              }
        }
Ejemplo n.º 39
0
        /// <summary>
        /// Solves the specified linear system of equations <i>Ax=b</i>.
        /// </summary>
        /// <param name="matrixA">The matrix A.</param>
        /// <param name="initialX">
        /// The initial guess for x. If this value is <see langword="null"/>, a zero vector will be used
        /// as initial guess.
        /// </param>
        /// <param name="vectorB">The vector b.</param>
        /// <returns>The solution vector x.</returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="matrixA"/> is <see langword="null"/>.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="vectorB"/> is <see langword="null"/>.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// <paramref name="matrixA"/> is not a square matrix.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// The number of elements of <paramref name="initialX"/> does not match.
        /// </exception>
        public override VectorF Solve(MatrixF matrixA, VectorF initialX, VectorF vectorB)
        {
            NumberOfIterations = 0;

              if (matrixA == null)
            throw new ArgumentNullException("matrixA");
              if (vectorB == null)
            throw new ArgumentNullException("vectorB");
              if (matrixA.IsSquare == false)
            throw new ArgumentException("Matrix A must be a square matrix.", "matrixA");
              if (matrixA.NumberOfRows != vectorB.NumberOfElements)
            throw new ArgumentException("The number of rows of A and b do not match.");
              if (initialX != null && initialX.NumberOfElements != vectorB.NumberOfElements)
            throw new ArgumentException("The number of elements of the initial guess for x and b do not match.");

              VectorF xOld = initialX ?? new VectorF(vectorB.NumberOfElements);
              VectorF xNew = new VectorF(vectorB.NumberOfElements);
              bool isConverged = false;
              // Make iterations until max iteration count or the result has converged.
              for (int i = 0; i < MaxNumberOfIterations && !isConverged; i++)
              {
            for (int j=0; j<vectorB.NumberOfElements; j++)
            {
              float delta = 0;
              for (int k=0; k < j; k++)
            delta += matrixA[j, k] * xNew[k];

              for (int k=j+1; k < vectorB.NumberOfElements; k++)
            delta += matrixA[j, k] * xOld[k];

              delta = (vectorB[j] - delta) / matrixA[j, j];
              xNew[j] = xOld[j] + RelaxationFactor * (delta - xOld[j]);
            }

            // Test convergence
            isConverged = VectorF.AreNumericallyEqual(xOld, xNew, Epsilon);

            xOld = xNew.Clone();
            NumberOfIterations = i + 1;
              }

              return xNew;
        }
Ejemplo n.º 40
0
        public void Test6()
        {
            MatrixF A = new MatrixF(new float[, ] {
                { -21, 2, -4, 0 },
                { 2, 3, 0.1f, -1 },
                { 2, 10, 111.1f, -11 },
                { 23, 112, 111.1f, -143 }
            });
            VectorF b = new VectorF(new float[] { 20, 28, -12, 0.1f });

            JacobiMethodF solver = new JacobiMethodF();

            solver.MaxNumberOfIterations = 10;
            VectorF x = solver.Solve(A, null, b);

            VectorF solution = MatrixF.SolveLinearEquations(A, b);

            Assert.IsFalse(VectorF.AreNumericallyEqual(solution, x));
            Assert.AreEqual(10, solver.NumberOfIterations);
        }
Ejemplo n.º 41
0
        public void Test7()
        {
            MatrixF A = new MatrixF(new float[, ] {
                { -21, 2, -4, 0 },
                { 2, 3, 0.1f, -1 },
                { 2, 10, 111.1f, -11 },
                { 23, 112, 111.1f, -143 }
            });
            VectorF b = new VectorF(new float[] { 20, 28, -12, 0.1f });

            SorMethodF solver = new SorMethodF();

            solver.Epsilon = 0.1f;
            VectorF x = solver.Solve(A, null, b);

            VectorF solution = MatrixF.SolveLinearEquations(A, b);

            Assert.IsTrue(VectorF.AreNumericallyEqual(solution, x, 0.1f));
            Assert.IsFalse(VectorF.AreNumericallyEqual(solution, x));
            Assert.Greater(12, solver.NumberOfIterations); // For normal accuracy (EpsilonF) we need 12 iterations.
        }
        public void TestMatricesWithFullRank()
        {
            MatrixF a = new MatrixF(new float[,] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, -9 } });
              SingularValueDecompositionF svd = new SingularValueDecompositionF(a);
              Assert.AreEqual(3, svd.NumericalRank);
              Assert.IsTrue(MatrixF.AreNumericallyEqual(a, svd.U * svd.S * svd.V.Transposed));
              Assert.AreEqual(svd.SingularValues[0], svd.Norm2);
              float condNumber = svd.ConditionNumber;
              svd = new SingularValueDecompositionF(a.Transposed);
              Assert.AreEqual(3, svd.NumericalRank);
              Assert.IsTrue(MatrixF.AreNumericallyEqual(a.Transposed, svd.U * svd.S * svd.V.Transposed));
              Assert.AreEqual(svd.SingularValues[0], svd.Norm2);
              condNumber = svd.ConditionNumber;

              a = new MatrixF(new float[,] { { 1, 2 }, { 4, 5 }, { 4, 5 } });
              svd = new SingularValueDecompositionF(a);
              Assert.AreEqual(2, svd.NumericalRank);
              Assert.IsTrue(MatrixF.AreNumericallyEqual(a, svd.U * svd.S * svd.V.Transposed));
              Assert.AreEqual(svd.SingularValues[0], svd.Norm2);
              condNumber = svd.ConditionNumber;
        }
Ejemplo n.º 43
0
        /// <summary>
        /// Returns outputs based on inputs going through the neural network
        /// </summary>
        /// <param name="_inputs"></param>
        /// <returns></returns>
        public float[] FeedForward(float[] _inputs)
        {
            // create matrix from inputs
            List <MatrixF> m = new List <MatrixF>();

            m.Add(MatrixF.FromArray(_inputs));

            // calculate hidden layers outputs
            for (int i = 0; i < numHiddenLayers; i++)
            {
                m.Add(MatrixF.DotProduct(weightMatrixes[i], m[i]));
                m[i + 1].Add(biasMatrixes[i]);
                Activate(m[i + 1]);
            }

            // calculate output layer output
            m.Add(MatrixF.DotProduct(weightMatrixes[weightMatrixes.Count - 1], m[m.Count - 1]));
            m[m.Count - 1].Add(biasMatrixes[biasMatrixes.Count - 1]);
            Activate(m[m.Count - 1]);

            return(MatrixF.ToArray(m[m.Count - 1]));
        }
        public void TestWithNaNValues()
        {
            MatrixF a = new MatrixF(new [,] {{ 0, float.NaN, 2 },
                                       { 1, 4, 3 },
                                        { 2, 3, 5}});

              var d = new EigenvalueDecompositionF(a);
              foreach (var element in d.RealEigenvalues.ToList())
            Assert.IsNaN(element);
              foreach (var element in d.ImaginaryEigenvalues.ToList())
            Assert.IsNaN(element);
              foreach (var element in d.V.ToList(MatrixOrder.RowMajor))
            Assert.IsNaN(element);

              d = new EigenvalueDecompositionF(new MatrixF(4, 4, float.NaN));
              foreach (var element in d.RealEigenvalues.ToList())
            Assert.IsNaN(element);
              foreach (var element in d.ImaginaryEigenvalues.ToList())
            Assert.IsNaN(element);
              foreach (var element in d.V.ToList(MatrixOrder.RowMajor))
            Assert.IsNaN(element);
        }
Ejemplo n.º 45
0
        public void TestMatricesWithFullRank()
        {
            MatrixF a = new MatrixF(new float[, ] {
                { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, -9 }
            });
            QRDecompositionF qr = new QRDecompositionF(a);

            Assert.AreEqual(true, qr.HasNumericallyFullRank);
            Assert.IsTrue(MatrixF.AreNumericallyEqual(a, qr.Q * qr.R));
            qr = new QRDecompositionF(a.Transposed);
            Assert.AreEqual(true, qr.HasNumericallyFullRank);
            Assert.IsTrue(MatrixF.AreNumericallyEqual(a.Transposed, qr.Q * qr.R));

            a = new MatrixF(new float[, ] {
                { 1, 2 }, { 4, 5 }, { 4, 5 }
            });
            qr = new QRDecompositionF(a);
            Assert.AreEqual(true, qr.HasNumericallyFullRank);
            Assert.IsTrue(MatrixF.AreNumericallyEqual(a, qr.Q * qr.R));

            MatrixF h = qr.H; // Just call this one to see if it runs through.
        }
Ejemplo n.º 46
0
        public void ToMatrixF()
        {
            Matrix22F m22 = new Matrix22F(1, 2, 3, 4);

            MatrixF m = m22.ToMatrixF();

            for (int i = 0; i < 2; i++)
            {
                for (int j = 0; j < 2; j++)
                {
                    Assert.AreEqual(i * 2 + j + 1, m[i, j]);
                }
            }

            m = m22;
            for (int i = 0; i < 2; i++)
            {
                for (int j = 0; j < 2; j++)
                {
                    Assert.AreEqual(i * 2 + j + 1, m[i, j]);
                }
            }
        }
Ejemplo n.º 47
0
        public void ToMatrixF()
        {
            Matrix m33 = new Matrix(1, 2, 3, 4, 5, 6, 7, 8, 9);

            MatrixF m = m33.ToMatrixF();

            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    Assert.AreEqual(i * 3 + j + 1, m[i, j]);
                }
            }

            m = m33;
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    Assert.AreEqual(i * 3 + j + 1, m[i, j]);
                }
            }
        }
Ejemplo n.º 48
0
        public void TestWithNaNValues()
        {
            MatrixF a = new MatrixF(new[, ] {
                { 0, float.NaN, 2 },
                { 1, 4, 3 },
                { 2, 3, 5 }
            });

            var d = new SingularValueDecompositionF(a);

            foreach (var element in d.SingularValues.ToList())
            {
                Assert.IsNaN(element);
            }
            foreach (var element in d.U.ToList(MatrixOrder.RowMajor))
            {
                Assert.IsNaN(element);
            }
            foreach (var element in d.V.ToList(MatrixOrder.RowMajor))
            {
                Assert.IsNaN(element);
            }

            d = new SingularValueDecompositionF(new MatrixF(4, 3, float.NaN));
            foreach (var element in d.SingularValues.ToList())
            {
                Assert.IsNaN(element);
            }
            foreach (var element in d.U.ToList(MatrixOrder.RowMajor))
            {
                Assert.IsNaN(element);
            }
            foreach (var element in d.V.ToList(MatrixOrder.RowMajor))
            {
                Assert.IsNaN(element);
            }
        }
Ejemplo n.º 49
0
        public void Absolute()
        {
            float[] values = new float[] { -1.0f, -2.0f, -3.0f,
                                     -4.0f, -5.0f, -6.0f,
                                     -7.0f, -8.0f, -9.0f };
              MatrixF m = new MatrixF(3, 3, values, MatrixOrder.RowMajor);

              MatrixF absolute = m.Clone();
              absolute.Absolute();
              for (int i = 0; i < absolute.NumberOfRows; i++)
            for (int j = 0; j < absolute.NumberOfColumns; j++)
              Assert.AreEqual(i * absolute.NumberOfColumns + j + 1, absolute[i, j]);

              absolute = MatrixF.Absolute(m);
              for (int i = 0; i < absolute.NumberOfRows; i++)
            for (int j = 0; j < absolute.NumberOfColumns; j++)
              Assert.AreEqual(i * absolute.NumberOfColumns + j + 1, absolute[i, j]);

              values = new float[] { 1.0f, 2.0f, 3.0f,
                             4.0f, 5.0f, 6.0f,
                             7.0f, 8.0f, 9.0f };
              m = new MatrixF(3, 3, values, MatrixOrder.RowMajor);

              absolute = m.Clone();
              absolute.Absolute();
              for (int i = 0; i < absolute.NumberOfRows; i++)
            for (int j = 0; j < absolute.NumberOfColumns; j++)
              Assert.AreEqual(i * absolute.NumberOfColumns + j + 1, absolute[i, j]);

              absolute = MatrixF.Absolute(m);
              for (int i = 0; i < absolute.NumberOfRows; i++)
            for (int j = 0; j < absolute.NumberOfColumns; j++)
              Assert.AreEqual(i * absolute.NumberOfColumns + j + 1, absolute[i, j]);

              Assert.IsNull(MatrixF.Absolute(null));
        }
Ejemplo n.º 50
0
        /// <summary>
        /// Creates a new Neural Network
        /// </summary>
        /// <param name="_inputs">number of inputs</param>
        /// <param name="_outputs">number of output</param>
        /// <param name="_hiddenNodes">number of neurons per hidden layer</param>
        public NeuralNetwork(int _inputs, int _hiddenNodes, int _outputs, int _numHiddenLayers = 1)
        {
            inputs          = _inputs;
            outputs         = _outputs;
            hiddenNodes     = _hiddenNodes;
            numHiddenLayers = _numHiddenLayers;

            // matrix of weights to use with layers
            weightMatrixes = new List <MatrixF>();
            weightMatrixes.Add(MatrixF.RandomMatrix(hiddenNodes, inputs));
            for (int i = 0; i < _numHiddenLayers - 1; i++)
            {
                weightMatrixes.Add(MatrixF.RandomMatrix(hiddenNodes, hiddenNodes));
            }
            weightMatrixes.Add(MatrixF.RandomMatrix(outputs, hiddenNodes));

            // very tall matrix of bias to use with layers
            biasMatrixes = new List <MatrixF>();
            for (int i = 0; i < _numHiddenLayers; i++)
            {
                biasMatrixes.Add(MatrixF.RandomMatrix(hiddenNodes, 1));
            }
            biasMatrixes.Add(MatrixF.RandomMatrix(outputs, 1));
        }
Ejemplo n.º 51
0
        // This method shows how to solve linear systems of equations.
        private void SolveLinearSystems()
        {
            var debugRenderer = GraphicsScreen.DebugRenderer2D;

            debugRenderer.DrawText("----- SolveLinearSystems Example:");

            // ----- Part 1: We want to solve following system of equations:
            {
                //  3x + 4y - 10z =  6
                // -7x + 9y       =  0
                //   x - 2y + 3z  = -8

                // We will represent this linear system using matrices and vectors:
                //   A * x = b
                // where the vector x contains the unknown variables.

                // Define the coefficient matrix A:
                Matrix33F A = new Matrix33F(3, 4, -10,
                                            -7, 9, 0,
                                            1, -2, 3);

                // Define the result vector b:
                Vector3F b = new Vector3F(6, 0, -8);

                // x can be computed with x = A^-1 * b.
                Vector3F x = A.Inverse * b;
                // Note: A.Inverse will throw an exception if A is not invertible.

                // Check the result.
                if (Vector3F.AreNumericallyEqual(A * x, b))
                {
                    debugRenderer.DrawText("Solution is correct.\n"); // This message is written.
                }
                else
                {
                    debugRenderer.DrawText("Solution is incorrect.\n");
                }
            }

            // ----- Part 2: We want to solve following system of equations:
            {
                //  3x + 4y =  6
                // -7x + 9y =  1
                //   x - 2y = -1
                // This linear system is overdetermined - there are more equations than unknown.
                // We can use MatrixF.SolveLinearEquations() to find an approximate solution
                // using the least-squares method.

                // Define the coefficient matrix A:
                MatrixF A = new MatrixF(
                    new float[3, 2]
                {
                    { 3, 4 },
                    { -7, 9 },
                    { 1, -2 }
                });

                // Define the result vector b.
                // (MatrixF.SolveLinearEquations() takes b as MatrixF not VectorF!)
                MatrixF b = new MatrixF(
                    new float[3, 1]
                {
                    { 6 },
                    { 1 },
                    { -1 }
                });

                // Next we compute x.
                // MatrixF.SolveLinearEquations() computes the exact result if possible.
                // For overdetermined systems (A has more rows than columns) the least-
                // squares solution is computed.
                MatrixF x = MatrixF.SolveLinearEquations(A, b);

                // The result x is an approximate solution for the above overdetermined linear system.
                debugRenderer.DrawText("Result: x = " + x[0, 0] + ", y = " + x[1, 0] + "\n");
            }
        }
Ejemplo n.º 52
0
        //--------------------------------------------------------------
        /// <summary>
        /// Returns the least squares solution for the equation <c>A * X = B</c>.
        /// </summary>
        /// <param name="matrixB">The matrix B with as many rows as A and any number of columns.</param>
        /// <returns>X with the least squares solution.</returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="matrixB"/> is <see langword="null"/>.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// The number of rows does not match.
        /// </exception>
        /// <exception cref="MathematicsException">
        /// The matrix A does not have full rank.
        /// </exception>
        public MatrixF SolveLinearEquations(MatrixF matrixB)
        {
            if (matrixB == null)
            throw new ArgumentNullException("matrixB");
              if (matrixB.NumberOfRows != _m)
            throw new ArgumentException("The number of rows does not match.", "matrixB");
              if (HasNumericallyFullRank == false)
            throw new MathematicsException("The matrix does not have full rank.");

              // Copy right hand side
              MatrixF x = matrixB.Clone();

              // Compute Y = transpose(Q)*B
              for (int k = 0; k < _n; k++)
              {
            for (int j = 0; j < matrixB.NumberOfColumns; j++)
            {
              float 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 < matrixB.NumberOfColumns; j++)
              x[k, j] /= _rDiagonal[k];
            for (int i = 0; i < k; i++)
              for (int j = 0; j < matrixB.NumberOfColumns; j++)
            x[i, j] -= x[k, j] * _qr[i, k];
              }
              return x.GetSubmatrix(0, _n - 1, 0, matrixB.NumberOfColumns - 1);
        }
Ejemplo n.º 53
0
        /// <summary>
        /// Solves the specified linear system of equations <i>Ax=b</i>.
        /// </summary>
        /// <param name="matrixA">The matrix A.</param>
        /// <param name="initialX">
        /// The initial guess for x. If this value is <see langword="null"/>, a zero vector will be used
        /// as initial guess.
        /// </param>
        /// <param name="vectorB">The vector b.</param>
        /// <returns>The solution vector x.</returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="matrixA"/> is <see langword="null"/>.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="vectorB"/> is <see langword="null"/>.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// <paramref name="matrixA"/> is not a square matrix.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// The number of elements of <paramref name="initialX"/> does not match.
        /// </exception>
        public override VectorF Solve(MatrixF matrixA, VectorF initialX, VectorF vectorB)
        {
            // TODO: We can possible improve the method by reordering after each step.
            // This can be done randomly or we sort by the "convergence" of the elements.
            // See book Physics-Based Animation.

            NumberOfIterations = 0;

            if (matrixA == null)
            {
                throw new ArgumentNullException("matrixA");
            }
            if (vectorB == null)
            {
                throw new ArgumentNullException("vectorB");
            }
            if (matrixA.IsSquare == false)
            {
                throw new ArgumentException("Matrix A must be a square matrix.", "matrixA");
            }
            if (matrixA.NumberOfRows != vectorB.NumberOfElements)
            {
                throw new ArgumentException("The number of rows of A and b do not match.");
            }
            if (initialX != null && initialX.NumberOfElements != vectorB.NumberOfElements)
            {
                throw new ArgumentException("The number of elements of the initial guess for x and b do not match.");
            }

            VectorF xOld        = initialX ?? new VectorF(vectorB.NumberOfElements);
            VectorF xNew        = new VectorF(vectorB.NumberOfElements);
            bool    isConverged = false;

            // Make iterations until max iteration count or the result has converged.
            for (int i = 0; i < MaxNumberOfIterations && !isConverged; i++)
            {
                for (int j = 0; j < vectorB.NumberOfElements; j++)
                {
                    float delta = 0;
                    for (int k = 0; k < j; k++)
                    {
                        delta += matrixA[j, k] * xNew[k];
                    }

                    for (int k = j + 1; k < vectorB.NumberOfElements; k++)
                    {
                        delta += matrixA[j, k] * xOld[k];
                    }

                    xNew[j] = (vectorB[j] - delta) / matrixA[j, j];
                }

                // Test convergence
                isConverged = VectorF.AreNumericallyEqual(xOld, xNew, Epsilon);

                xOld = xNew.Clone();
                NumberOfIterations = i + 1;
            }

            return(xNew);
        }
Ejemplo n.º 54
0
 public RotationMatrix(Vector3 rotation)
 {
     X = MatrixF.CreateRotationX(rotation.X);
     Y = MatrixF.CreateRotationY(rotation.Y);
     Z = MatrixF.CreateRotationZ(rotation.Z);
 }
Ejemplo n.º 55
0
        public static void ComputeBoundingCapsule(IList <Vector3> points, out float radius, out float height, out Pose pose)
        {
            if (points == null)
            {
                throw new ArgumentNullException("points");
            }

            // Covariance matrix.
            MatrixF cov = null;

            // ReSharper disable EmptyGeneralCatchClause
            try
            {
                if (points.Count > 4)
                {
                    // Reduce point list to convex hull.
                    DcelMesh     dcelMesh = CreateConvexHull(points);
                    TriangleMesh mesh     = dcelMesh.ToTriangleMesh();

                    // Use reduced point list - if we have found a useful one. (Line objects
                    // have not useful triangle mesh.)
                    if (mesh.Vertices.Count > 0)
                    {
                        points = mesh.Vertices;
                    }

                    cov = ComputeCovarianceMatrixFromSurface(mesh);
                }
            }
            catch
            {
            }
            // ReSharper restore EmptyGeneralCatchClause

            // If anything happens in the convex hull creation, we can still go on including the
            // interior points and compute the covariance matrix for the points instead of the
            // surface.
            if (cov == null || Numeric.IsNaN(cov.Determinant()))
            {
                cov = ComputeCovarianceMatrixFromPoints(points);
            }

            // Perform Eigenvalue decomposition.
            EigenvalueDecompositionF evd = new EigenvalueDecompositionF(cov);

            // v transforms from local coordinate space of the capsule into world space.
            var v = evd.V.ToMatrix();

            Debug.Assert(v.GetColumn(0).IsNumericallyNormalized);
            Debug.Assert(v.GetColumn(1).IsNumericallyNormalized);
            Debug.Assert(v.GetColumn(2).IsNumericallyNormalized);

            // v is like a rotation matrix, but the coordinate system is not necessarily right handed.
            // --> Make sure it is right-handed.
            v.SetColumn(2, Vector3.Cross(v.GetColumn(0), v.GetColumn(1)));

            // Make local Y the largest axis. (Y is the long capsule axis.)
            Vector3 eigenValues           = evd.RealEigenvalues.ToVector3();
            int     largestComponentIndex = eigenValues.IndexOfLargestComponent;

            if (largestComponentIndex != 1)
            {
                // Swap two columns to create a right handed rotation matrix.
                Vector3 colLargest = v.GetColumn(largestComponentIndex);
                Vector3 col1       = v.GetColumn(1);
                v.SetColumn(1, colLargest);
                v.SetColumn(largestComponentIndex, col1);
                v.SetColumn(2, Vector3.Cross(v.GetColumn(0), v.GetColumn(1)));
            }

            // Compute capsule for the orientation given by v.
            Vector3 center;

            ComputeBoundingCapsule(points, v, out radius, out height, out center);
            pose = new Pose(center, v);
        }
Ejemplo n.º 56
0
        //--------------------------------------------------------------
        /// <summary>
        /// Solves the equation <c>A * X = B</c>.
        /// </summary>
        /// <param name="matrixB">The matrix B with as many rows as A and any number of columns.</param>
        /// <returns>X, so that <c>A * X = B</c>.</returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="matrixB"/> is <see langword="null"/>.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// The number of rows does not match.
        /// </exception>
        /// <exception cref="MathematicsException">
        /// The matrix A is not symmetric and positive definite.
        /// </exception>
        public MatrixF SolveLinearEquations(MatrixF matrixB)
        {
            if (matrixB == null)
            throw new ArgumentNullException("matrixB");
              if (matrixB.NumberOfRows != L.NumberOfRows)
            throw new ArgumentException("The number of rows does not match.", "matrixB");
              if (IsSymmetricPositiveDefinite == false)
            throw new MathematicsException("The original matrix A is not symmetric and positive definite.");

              // Initialize x as a copy of B.
              MatrixF x = matrixB.Clone();

              // Solve L*Y = B.
              for (int k = 0; k < L.NumberOfRows; k++)
              {
            for (int j = 0; j < matrixB.NumberOfColumns; j++)
            {
              for (int i = 0; i < k; i++)
            x[k, j] -= x[i, j] * L[k, i];
              x[k, j] /= L[k, k];
            }
              }

              // Solve transpose(L) * X = Y.
              for (int k = L.NumberOfRows - 1; k >= 0; k--)
              {
            for (int j = 0; j < matrixB.NumberOfColumns; j++)
            {
              for (int i = k + 1; i < L.NumberOfRows; i++)
            x[k, j] -= x[i, j] * L[i, k];
              x[k, j] /= L[k, k];
            }
              }
              return x;
        }
Ejemplo n.º 57
0
        //--------------------------------------------------------------
        /// <summary>
        /// Called when <see cref="ScatteredInterpolationF.Setup"/> is called.
        /// </summary>
        /// <remarks>
        /// Here internal values can be computed from the registered reference pairs if required. It is
        /// assured that the reference data pairs have valid dimensions: All x values have the same
        /// number of elements and all y values have the same number of elements. All reference data
        /// values are not <see langword="null"/>.
        /// </remarks>
        /// <exception cref="MathematicsException">
        /// Cannot compute regression - try to choose different reference data pairs or another basis 
        /// function.
        /// </exception>
        protected override void OnSetup()
        {
            // Compute weights:
              // Make matrix Φ (also known as G).
              int numberOfPairs = Count;
              MatrixF G = new MatrixF(numberOfPairs, numberOfPairs);
              for (int r = 0; r < numberOfPairs; r++)  // rows
              {
            for (int c = 0; c < numberOfPairs; c++)  // columns
            {
              float radialArgument = DistanceFunction(GetX(r), GetX(c), c);
              G[r, c] = BasisFunction(radialArgument, c);
            }
              }

              // We look for the matrix W that contains the weights.
              // Each row resembles an n-dimensional weight.
              MatrixF W;

              // Make the matrix Y with the reference values, such that ideally Y = G * W.
              MatrixF Y = new MatrixF(numberOfPairs, GetY(0).NumberOfElements);
              for (int r = 0; r < numberOfPairs; r++)
            Y.SetRow(r, GetY(r));

              // Compute W as the least squares solution.
              try
              {
            W = MatrixF.SolveLinearEquations(G, Y);
              }
              catch (MathematicsException exception)
              {
            throw new MathematicsException("Cannot compute regression - try to choose different reference data pairs or another basis function.", exception);
              }

              // The rows of W are the weights.
              _weights = new VectorF[numberOfPairs];
              for (int r = 0; r < numberOfPairs; r++)
            _weights[r] = W.GetRow(r);
        }
 /// <overloads>
 /// <summary>
 /// Solves the specified linear system of equations <i>A * x = b</i>.
 /// </summary>
 /// </overloads>
 ///
 /// <summary>
 /// Solves the specified linear system of equations <i>A * x = b</i>.
 /// </summary>
 /// <param name="matrixA">The matrix A.</param>
 /// <param name="vectorB">The vector b.</param>
 /// <returns>The solution vector x.</returns>
 /// <remarks>
 /// A zero vector is used as initial guess for x.
 /// </remarks>
 public VectorF Solve(MatrixF matrixA, VectorF vectorB)
 {
     return(Solve(matrixA, null, vectorB));
 }
Ejemplo n.º 59
0
        /// <summary>
        /// Called when <see cref="IKSolver.Solve"/> is called.
        /// </summary>
        /// <param name="deltaTime">The current time step (in seconds).</param>
        protected override void OnSolve(float deltaTime)
        {
            if (NumberOfIterations <= 0)
            {
                return;
            }

            if (_isDirty)
            {
                if (!SkeletonPose.IsAncestorOrSelf(RootBoneIndex, TipBoneIndex))
                {
                    throw new ArgumentException("The RootBoneIndex and the TipBoneIndex do not form a valid bone chain.");
                }
            }

            _isDirty = false;

            var   skeleton         = SkeletonPose.Skeleton;
            bool  requiresBlending = RequiresBlending();
            float maxRotationAngle;
            bool  requiresLimiting = RequiresLimiting(deltaTime, out maxRotationAngle);

            if (requiresBlending || requiresLimiting)
            {
                // Remember original bone transforms for interpolation with the result at the end.
                // Transforms are stored from tip to root (reverse order!).
                _originalTransforms.Clear();

                int boneIndex = TipBoneIndex;
                while (true)
                {
                    _originalTransforms.Add(SkeletonPose.GetBoneTransform(boneIndex));

                    if (boneIndex == RootBoneIndex)
                    {
                        break;
                    }

                    boneIndex = skeleton.GetParent(boneIndex);
                }
            }

            int numberOfBones = SkeletonPose.GetNumberOfBones(RootBoneIndex, TipBoneIndex);

            // The transposed jacobian matrix.
            var jacobianTransposed = new MatrixF(numberOfBones, 6);

            // The force vector (3 linear and 3 angular (torque) entries).
            VectorF force = new VectorF(6);

            // The rotation axes of the bones.
            Vector3F[] axes = new Vector3F[numberOfBones];

            float toleranceSquared = AllowedDeviation * AllowedDeviation;

            // In each iteration we compute the jacobian matrix, compute the bone velocities
            // an make an euler integration step.
            for (int iteration = 0; iteration < NumberOfIterations; iteration++)
            {
                var tipBoneAbsolute = SkeletonPose.GetBonePoseAbsolute(TipBoneIndex);
                var tipAbsolute     = tipBoneAbsolute.ToParentPosition(TipOffset);
                var targetToTip     = tipAbsolute - Target;
                if (targetToTip.LengthSquared < toleranceSquared)
                {
                    if (iteration == 0)
                    {
                        return;
                    }

                    break;
                }

                // Loop from tip to root and fill Jacobian.
                // (See description of Jacobian Transpose method to see how the rotation axes and
                // Jacobian entries must look like).
                var currentBoneIndex = TipBoneIndex;
                int exitBoneIndex    = RootBoneIndex >= 0 ? skeleton.GetParent(RootBoneIndex) : -1;
                int i = numberOfBones;
                do
                {
                    i--;

                    // Compute rotation axis.
                    Vector3F currentJointAbsolute = SkeletonPose.GetBonePoseAbsolute(currentBoneIndex).Translation;
                    Vector3F jointToTarget        = Target - currentJointAbsolute;
                    Vector3F jointToTip           = tipAbsolute - currentJointAbsolute;
                    axes[i] = Vector3F.Cross(jointToTarget, jointToTip);
                    if (!axes[i].TryNormalize())
                    {
                        axes[i] = Vector3F.UnitX; // TODO: What should we really do in this case?
                    }
                    Vector3F jacobianColumnUpperPart = Vector3F.Cross(jointToTip, axes[i]);

                    // Fill J.
                    jacobianTransposed[i, 0] = jacobianColumnUpperPart.X;
                    jacobianTransposed[i, 1] = jacobianColumnUpperPart.Y;
                    jacobianTransposed[i, 2] = jacobianColumnUpperPart.Z;
                    jacobianTransposed[i, 3] = axes[i].X;
                    jacobianTransposed[i, 4] = axes[i].Y;
                    jacobianTransposed[i, 5] = axes[i].Z;

                    currentBoneIndex = skeleton.GetParent(currentBoneIndex);
                } while (currentBoneIndex != exitBoneIndex && currentBoneIndex >= 0);

                Debug.Assert(i == 0);

                // Set the force.
                force[0] = targetToTip.X;
                force[1] = targetToTip.Y;
                force[2] = targetToTip.Z;
                force[3] = 0;
                force[4] = 0;
                force[5] = 0;

                // Compute pseudo velocities.
                VectorF velocities = jacobianTransposed * force; // TODO: Garbage!

                // Euler integration step.
                currentBoneIndex = TipBoneIndex;
                i = numberOfBones;
                do
                {
                    i--;

                    // Rotation axis for this bone.
                    Vector3F axis = axes[i];
                    // Angle is computed using Euler integration with an arbitrary step size.
                    float angle = velocities[i] * StepSize;

                    // Apply rotation.
                    QuaternionF rotationChange = QuaternionF.CreateRotation(axis, angle);
                    SkeletonPose.RotateBoneAbsolute(currentBoneIndex, rotationChange);

                    currentBoneIndex = skeleton.GetParent(currentBoneIndex);
                } while (currentBoneIndex != exitBoneIndex && currentBoneIndex >= 0);

                // Call delegate that checks bone limits.
                if (LimitBoneTransforms != null)
                {
                    LimitBoneTransforms();
                }
            }

            if (requiresBlending || requiresLimiting)
            {
                // Apply weight and the angular velocity limit.
                int boneIndex = TipBoneIndex;
                int i         = 0;
                while (true)
                {
                    var originalTransform = _originalTransforms[i];
                    var targetTransform   = SkeletonPose.GetBoneTransform(boneIndex);

                    // Apply weight.
                    if (requiresBlending)
                    {
                        BlendBoneTransform(ref originalTransform, ref targetTransform);
                    }

                    // Apply angular velocity limit.
                    if (requiresLimiting)
                    {
                        LimitBoneTransform(ref originalTransform, ref targetTransform, maxRotationAngle);
                    }

                    SkeletonPose.SetBoneTransform(boneIndex, targetTransform);

                    if (boneIndex == RootBoneIndex)
                    {
                        break;
                    }

                    boneIndex = skeleton.GetParent(boneIndex);
                    i++;
                }
            }

            _originalTransforms.Clear();
        }
 /// <summary>
 /// Solves the specified linear system of equations <i>A * x = b</i> using an initial guess.
 /// </summary>
 /// <param name="matrixA">The matrix A.</param>
 /// <param name="initialX">
 /// The initial guess for x. If this value is <see langword="null"/>, a zero vector will be used
 /// as initial guess.
 /// </param>
 /// <param name="vectorB">The vector b.</param>
 /// <returns>The solution vector x.</returns>
 public abstract VectorF Solve(MatrixF matrixA, VectorF initialX, VectorF vectorB);