Ejemplo n.º 1
0
            public void different_sizes_are_not_equal()
            {
                var a = new VectorF(2);

                a.Set(0, 9.0f);
                a.Set(1, -10.3f);
                var b = new VectorF(3);

                b.Set(0, 9.0f);
                b.Set(1, -10.3f);

                Assert.False(a.Equals(b));
                Assert.False(b.Equals(a));
            }
Ejemplo n.º 2
0
            public void different_ref_same_components_are_equal()
            {
                var a = new VectorF(2);

                a.Set(0, 9.0f);
                a.Set(1, -10.3f);
                var b = new VectorF(2);

                b.Set(0, 9.0f);
                b.Set(1, -10.3f);

                Assert.True(a.Equals((object)b));
                Assert.True(b.Equals((object)a));
            }
Ejemplo n.º 3
0
            public void different_components_are_not_equal()
            {
                var a = new VectorF(2);

                a.Set(0, 9.0f);
                a.Set(1, -10.3f);
                var b = new VectorF(2);

                b.Set(0, -9.0f);
                b.Set(1, 20.4f);

                Assert.False(a.Equals((object)b));
                Assert.False(b.Equals((object)a));
            }
Ejemplo n.º 4
0
            public void example_1()
            {
                var left = new VectorF(5);

                left.Set(0, 1);
                var right = new VectorF(5);

                right.Set(0, 1);
                right.Set(2, 1);
                var expected = (float)(Math.Acos(1.0 / Math.Sqrt(2.0)));

                var actual = left.GetAngleBetween(right);

                Assert.Equal(expected, actual, 5);
            }
Ejemplo n.º 5
0
            public void can_get_quotient_vector()
            {
                var source = new VectorF(2);

                source.Set(0, 4.5f);
                source.Set(1, 888f);
                var expected = new VectorF(2);

                expected.Set(0, 4.5f / 4.0f);
                expected.Set(1, 888f / 4.0f);

                var actual = source.GetQuotient(4);

                Assert.Equal(expected, actual);
            }
Ejemplo n.º 6
0
            public void can_negate()
            {
                var actual = new VectorF(2);

                actual.Set(0, -8.8f);
                actual.Set(1, 6.1f);
                var expected = new VectorF(2);

                expected.Set(0, 8.8f);
                expected.Set(1, -6.1f);

                actual.Negate();

                Assert.Equal(expected, actual);
            }
Ejemplo n.º 7
0
            public void can_divide_vector()
            {
                var actual = new VectorF(2);

                actual.Set(0, 4.5f);
                actual.Set(1, 888f);
                var expected = new VectorF(2);

                expected.Set(0, 4.5f / 4.0f);
                expected.Set(1, 888f / 4.0f);

                actual.Divide(4);

                Assert.Equal(expected, actual);
            }
Ejemplo n.º 8
0
            public void can_get_negative_vector()
            {
                var source = new VectorF(2);

                source.Set(0, 1.5f);
                source.Set(1, -6f);
                var expected = new VectorF(2);

                expected.Set(0, -1.5f);
                expected.Set(1, 6f);

                var actual = source.GetNegative();

                Assert.Equal(expected, actual);
            }
Ejemplo n.º 9
0
            public void copy_constructor_copies_all_componenets()
            {
                var expected = new VectorF(5);

                expected.Set(0, 0);
                expected.Set(1, 1);
                expected.Set(2, 2);
                expected.Set(3, 3);
                expected.Set(4, 4);

                var actual = new VectorF(expected);

                Assert.NotSame(expected, actual);
                Assert.Equal(expected, actual);
            }
Ejemplo n.º 10
0
            public void array_constructor_assigns_componenets_and_length()
            {
                var components = new float[] { 4, 5, 6, 7 };
                var expected   = new VectorF(4);

                expected.Set(0, 4);
                expected.Set(1, 5);
                expected.Set(2, 6);
                expected.Set(3, 7);

                var actual = new VectorF(components);

                Assert.Equal(components.Length, actual.Dimensions);
                Assert.Equal(expected, actual);
            }
Ejemplo n.º 11
0
            public void right_angle_is_half_pi()
            {
                var left = new VectorF(4);

                left.Set(0, 1);
                left.Set(2, 1);
                var right = new VectorF(4);

                right.Set(1, 1);
                right.Set(3, 1);
                var expected = (float)(Math.PI / 2.0);

                var actual = left.GetAngleBetween(right);

                Assert.Equal(expected, actual, 5);
            }
Ejemplo n.º 12
0
            public void get_all_element_for_dim_5()
            {
                var v = new VectorF(5);

                v.Set(0, -1.0f);
                v.Set(1, 5.7f);
                v.Set(2, -0.4f);
                v.Set(3, 9.0f);
                v.Set(4, -101.1f);

                Assert.Equal(-1.0f, v.Get(0));
                Assert.Equal(5.7f, v.Get(1));
                Assert.Equal(-0.4f, v.Get(2));
                Assert.Equal(9.0f, v.Get(3));
                Assert.Equal(-101.1f, v.Get(4));
            }
Ejemplo n.º 13
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.º 14
0
            public void can_get_scaled_vector()
            {
                var source = new VectorF(3);

                source.Set(0, 1);
                source.Set(1, 2);
                source.Set(2, -4);
                var expected = new VectorF(3);

                expected.Set(0, 3);
                expected.Set(1, 6);
                expected.Set(2, -12);

                var actual = source.GetScaled(3);

                Assert.Equal(expected, actual);
            }
Ejemplo n.º 15
0
            public void can_get_scaled_vector()
            {
                var actual = new VectorF(3);

                actual.Set(0, 1);
                actual.Set(1, 2);
                actual.Set(2, -4);
                var expected = new VectorF(3);

                expected.Set(0, 3);
                expected.Set(1, 6);
                expected.Set(2, -12);

                actual.Scale(3);

                Assert.Equal(expected, actual);
            }
Ejemplo n.º 16
0
            public void array_constructor_copies_all_componenets()
            {
                var arrayValues = new[] { 1.0f, 2.0f, 3.0f };
                var expected    = new VectorF(3);

                expected.Set(0, 1.0f);
                expected.Set(1, 2.0f);
                expected.Set(2, 3.0f);

                var actual = new VectorF(arrayValues);

                arrayValues[0] = -99.0f;
                arrayValues[1] = -99.0f;
                arrayValues[2] = -99.0f;

                Assert.Equal(expected, actual);
            }
Ejemplo n.º 17
0
            public void can_find_distance_in_both_directions()
            {
                var a = new VectorF(5);

                a.Set(0, 1);
                a.Set(1, 2);
                a.Set(2, 3);
                var b = new VectorF(5);

                b.Set(1, -9);
                b.Set(2, 5);
                b.Set(4, 3);
                var expected = a.GetDistanceSquared(b);

                var actual = b.GetDistanceSquared(a);

                Assert.Equal(expected, actual);
            }
Ejemplo n.º 18
0
            public void subtracting_vectors_leaves_right_unchanged()
            {
                var left = new VectorF(3);

                left.Set(0, 1);
                left.Set(1, 10);
                left.Set(2, 6);
                var right = new VectorF(3);

                right.Set(0, 10);
                right.Set(1, 3);
                right.Set(2, 1);
                var expectedRight = new VectorF(right);

                left.Subtract(right);

                Assert.Equal(expectedRight, right);
            }
Ejemplo n.º 19
0
            public void can_get_dot()
            {
                var left = new VectorF(3);

                left.Set(0, 1.2f);
                left.Set(1, 3.0f);
                left.Set(2, -9.0f);
                var right = new VectorF(3);

                right.Set(0, -1.1f);
                right.Set(1, 6.7f);
                right.Set(2, 3.3f);
                var expected = (left[0] * right[0]) + (left[1] * right[1]) + (left[2] * right[2]);

                var actual = left.GetDot(right);

                Assert.Equal(expected, actual, 5);
            }
Ejemplo n.º 20
0
            public void can_find_distance()
            {
                var a = new VectorF(5);

                a.Set(0, 1);
                a.Set(1, 2);
                a.Set(2, 3);
                var b = new VectorF(5);

                b.Set(1, -9);
                b.Set(2, 5);
                b.Set(3, 2);
                b.Set(4, 3);
                var expected = 139.0;

                var actual = a.GetDistanceSquared(b);

                Assert.Equal(expected, actual);
            }
Ejemplo n.º 21
0
            public void can_create_axis_unit_vector(int size, int dimension)
            {
                var expected = new VectorF(size);

                expected.Set(dimension, 1.0f);

                var actual = VectorF.CreateUnit(size, dimension);

                Assert.Equal(expected, actual);
            }
Ejemplo n.º 22
0
        protected VectorF CreateIncremenetal(int dimension)
        {
            var vector = new VectorF(dimension);

            for (int i = 0; i < dimension; i++)
            {
                vector.Set(i, i + 1);
            }

            return(vector);
        }
Ejemplo n.º 23
0
            public void adding_vectors_does_not_mutate_operands()
            {
                var left = new VectorF(3);

                left.Set(0, 1);
                left.Set(1, 3);
                left.Set(2, -4);
                var expectedLeft = new VectorF(left);
                var right        = new VectorF(3);

                right.Set(0, -10);
                right.Set(1, 4);
                right.Set(2, -20);
                var expectedRight = new VectorF(right);

                left.GetSum(right);

                Assert.Equal(expectedRight, right);
                Assert.Equal(expectedLeft, left);
            }
Ejemplo n.º 24
0
            public void subtracting_vectors_leaves_operands_unchanged()
            {
                var left = new VectorF(3);

                left.Set(0, 1);
                left.Set(1, 10);
                left.Set(2, 6);
                var expectedLeft = new VectorF(left);
                var right        = new VectorF(3);

                right.Set(0, 10);
                right.Set(1, 3);
                right.Set(2, 1);
                var expectedRight = new VectorF(right);

                var result = left.GetDiffernce(right);

                Assert.Equal(expectedLeft, left);
                Assert.Equal(expectedRight, right);
            }
Ejemplo n.º 25
0
            public void can_add_vectors_of_same_size()
            {
                var actual = new VectorF(3);

                actual.Set(0, 1);
                actual.Set(1, 3);
                actual.Set(2, -4);
                var right = new VectorF(3);

                right.Set(0, -10);
                right.Set(1, 4);
                right.Set(2, -20);
                var expected = new VectorF(3);

                expected.Set(0, -9);
                expected.Set(1, 7);
                expected.Set(2, -24);

                actual.Add(right);

                Assert.Equal(expected, actual);
            }
Ejemplo n.º 26
0
            public void subtracting_vector_produces_diff_vector()
            {
                var left = new VectorF(3);

                left.Set(0, 1);
                left.Set(1, 10);
                left.Set(2, 6);
                var right = new VectorF(3);

                right.Set(0, 10);
                right.Set(1, 3);
                right.Set(2, 1);
                var expected = new VectorF(3);

                expected.Set(0, -9);
                expected.Set(1, 7);
                expected.Set(2, 5);

                var actual = left.GetDiffernce(right);

                Assert.Equal(expected, actual);
            }
Ejemplo n.º 27
0
            public void subtracting_vector_subtracts_from_components()
            {
                var actual = new VectorF(3);

                actual.Set(0, 1);
                actual.Set(1, 10);
                actual.Set(2, 6);
                var right = new VectorF(3);

                right.Set(0, 10);
                right.Set(1, 3);
                right.Set(2, 1);
                var expected = new VectorF(3);

                expected.Set(0, -9);
                expected.Set(1, 7);
                expected.Set(2, 5);

                actual.Subtract(right);

                Assert.Equal(expected, actual);
            }
Ejemplo n.º 28
0
        public void Set()
        {
            VectorF v = new VectorF(5);
              v.Set(0.123f);
              Assert.AreEqual(5, v.NumberOfElements);
              for (int i = 0; i < 5; i++)
            Assert.AreEqual(0.123f, v[i]);

              v.Set(new VectorF(new float[] { 1, 2, 3, 4, 5 }));
              Assert.AreEqual(5, v.NumberOfElements);
              Assert.AreEqual(1, v[0]);
              Assert.AreEqual(2, v[1]);
              Assert.AreEqual(3, v[2]);
              Assert.AreEqual(4, v[3]);
              Assert.AreEqual(5, v[4]);

              v.Set(new float[] { 1, 2, 3, 4, 5 });
              Assert.AreEqual(5, v.NumberOfElements);
              Assert.AreEqual(1, v[0]);
              Assert.AreEqual(2, v[1]);
              Assert.AreEqual(3, v[2]);
              Assert.AreEqual(4, v[3]);
              Assert.AreEqual(5, v[4]);

              v.Set(new List<float>(new float[] { 1, 2, 3, 4, 5 }));
              Assert.AreEqual(5, v.NumberOfElements);
              Assert.AreEqual(1, v[0]);
              Assert.AreEqual(2, v[1]);
              Assert.AreEqual(3, v[2]);
              Assert.AreEqual(4, v[3]);
              Assert.AreEqual(5, v[4]);
        }
Ejemplo n.º 29
0
        public void ProjectTo2()
        {
            VectorF unitX = new VectorF(new float[] { 1, 0, 0, 0 });
              VectorF unitY = new VectorF(new float[] { 0, 1, 0, 0 });
              VectorF unitZ = new VectorF(new float[] { 0, 0, 1, 0 });
              VectorF one = new VectorF(new float[] { 1, 1, 1, 1 });

              // Project (1, 1, 1) to axes
              VectorF projection = new VectorF(new float[] { 1, 1, 1, 0 });
              projection.ProjectTo(unitX);
              Assert.AreEqual(unitX, projection);
              projection.Set(one);
              projection.ProjectTo(unitY);
              Assert.AreEqual(unitY, projection);
              projection.Set(one);
              projection.ProjectTo(unitZ);
              Assert.AreEqual(unitZ, projection);

              // Project axes to (1, 1, 1)
              VectorF expected = new VectorF(new float[] { 1, 1, 1, 0 }) / 3.0f;
              projection.Set(unitX);
              projection.ProjectTo(new VectorF(new float[] { 1, 1, 1, 0 }));
              Assert.AreEqual(expected, projection);
              projection.Set(unitY);
              projection.ProjectTo(new VectorF(new float[] { 1, 1, 1, 0 }));
              Assert.AreEqual(expected, projection);
              projection.Set(unitZ);
              projection.ProjectTo(new VectorF(new float[] { 1, 1, 1, 0 }));
              Assert.AreEqual(expected, projection);
        }
        public SingularValueDecompositionF(MatrixF matrixA)
        {
            if (matrixA == null)
            throw new ArgumentNullException("matrixA");

              // Derived from LINPACK code.
              // Initialize.
              _m = matrixA.NumberOfRows;
              _n = matrixA.NumberOfColumns;
              MatrixF matrixAClone = matrixA.Clone();

              if (_m < _n)
            throw new ArgumentException("The number of rows must be greater than or equal to the number of columns.", "matrixA");

              int nu = Math.Min(_m, _n);
              _s = new VectorF(Math.Min(_m + 1, _n));
              _u = new MatrixF(_m, nu);     //Jama getU() returns new Matrix(U,_m,Math.min(_m+1,_n)) ?!
              _v = new MatrixF(_n, _n);
              float[] e = new float[_n];
              float[] work = new float[_m];

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

              // By default, we calculate U and V. To calculate only U or V we can set one of the following
              // two constants to false. (This optimization is not yet tested.)
              const bool wantu = true;
              const bool wantv = true;

              // Reduce A to bidiagonal form, storing the diagonal elements
              // in s and the super-diagonal elements in e.

              int nct = Math.Min(_m - 1, _n);
              int nrt = Math.Max(0, Math.Min(_n - 2, _m));
              for (int k = 0; k < 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] = MathHelper.Hypotenuse(_s[k], matrixAClone[i, k]);

              if (_s[k] != 0)
              {
            if (matrixAClone[k, k] < 0)
              _s[k] = -_s[k];

            for (int i = k; i < _m; i++)
              matrixAClone[i, k] /= _s[k];

            matrixAClone[k, k] += 1;
              }

              _s[k] = -_s[k];
            }
            for (int j = k + 1; j < _n; j++)
            {
              if ((k < nct) && (_s[k] != 0))
              {
            // Apply the transformation.
            float t = 0;
            for (int i = k; i < _m; i++)
              t += matrixAClone[i, k] * matrixAClone[i, j];

            t = -t / matrixAClone[k, k];
            for (int i = k; i < _m; i++)
              matrixAClone[i, j] += t * matrixAClone[i, k];
              }

              // Place the k-th row of A into e for the
              // subsequent calculation of the row transformation.

              e[j] = matrixAClone[k, j];
            }

            if (wantu & (k < nct))
            {
              // Place the transformation in U for subsequent back
              // multiplication.
              for (int i = k; i < _m; i++)
            _u[i, k] = matrixAClone[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] = MathHelper.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;

            for (int j = k + 1; j < _n; j++)
              for (int i = k + 1; i < _m; i++)
                work[i] += e[j] * matrixAClone[i, j];

            for (int j = k + 1; j < _n; j++)
            {
              float t = -e[j] / e[k + 1];
              for (int i = k + 1; i < _m; i++)
                matrixAClone[i, j] += 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 = Math.Min(_n, _m + 1);
              if (nct < _n)
            _s[nct] = matrixAClone[nct, nct];

              if (_m < p)
            _s[p - 1] = 0;

              if (nrt + 1 < p)
            e[nrt] = matrixAClone[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)
              {
            for (int j = k + 1; j < nu; j++)
            {
              float t = 0;
              for (int i = k; i < _m; i++)
                t += _u[i, k] * _u[i, j];

              t = -t / _u[k, k];
              for (int i = k; i < _m; i++)
                _u[i, j] += t * _u[i, k];

            }
            for (int i = k; i < _m; i++)
              _u[i, k] = -_u[i, k];

            _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.0))
              {
            for (int j = k + 1; j < nu; j++)
            {
              float t = 0;
              for (int i = k + 1; i < _n; i++)
                t += _v[i, k] * _v[i, j];

              t = -t / _v[k + 1, k];
              for (int i = k + 1; i < _n; i++)
                _v[i, j] += t * _v[i, k];
            }
              }

              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;
              double eps = (float)Math.Pow(2, -23);     // 2^-52 for double
              double tiny = (float)Math.Pow(2, -100);   // 2^-100 for float is an estimation by HelmutG
              // Original: 2^-966 for double
              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 (Math.Abs(e[k]) <= tiny + eps * (Math.Abs(_s[k]) + 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;

            float t = (ks != p ? Math.Abs(e[ks]) : 0) + (ks != k + 1 ? Math.Abs(e[ks - 1]) : 0);
            if (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:
            {
              float f = e[p - 2];
              e[p - 2] = 0;
              for (int j = p - 2; j >= k; j--)
              {
                float t = MathHelper.Hypotenuse(_s[j], f);
                float cs = _s[j] / t;
                float 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:
            {
              float f = e[k - 1];
              e[k - 1] = 0;
              for (int j = k; j < p; j++)
              {
                float t = MathHelper.Hypotenuse(_s[j], f);
                float cs = _s[j] / t;
                float 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.

              float scale = Math.Max(Math.Max(Math.Max(Math.Max(
                      Math.Abs(_s[p - 1]), Math.Abs(_s[p - 2])), Math.Abs(e[p - 2])),
                      Math.Abs(_s[k])), Math.Abs(e[k]));
              float sp = _s[p - 1] / scale;
              float spm1 = _s[p - 2] / scale;
              float epm1 = e[p - 2] / scale;
              float sk = _s[k] / scale;
              float ek = e[k] / scale;
              float b = ((spm1 + sp) * (spm1 - sp) + epm1 * epm1) / 2;
              float c = (sp * epm1) * (sp * epm1);
              float shift = 0;
              if ((b != 0.0) | (c != 0.0))
              {
                shift = (float)Math.Sqrt(b * b + c);
                if (b < 0.0)
                  shift = -shift;

                shift = c / (b + shift);
              }
              float f = (sk + sp) * (sk - sp) + shift;
              float g = sk * ek;

              // Chase zeros.

              for (int j = k; j < p - 1; j++)
              {
                float t = MathHelper.Hypotenuse(f, g);
                float cs = f / t;
                float 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)
                {
                  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;
                  }
                }

                t = MathHelper.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))
                {
                  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;
                  }
                }
              }

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

              // Convergence.

              case 4:
            {
              // Make the singular values positive.

              if (_s[k] <= 0.0)
              {
                _s[k] = (_s[k] < 0.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;

                float t = _s[k];
                _s[k] = _s[k + 1];
                _s[k + 1] = t;
                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;
            }
              }
        }
Ejemplo n.º 31
0
 public void SetWithArrayShouldThrowArgumentNullException()
 {
     VectorF v = new VectorF(1);
       v.Set((float[])null);
 }
Ejemplo n.º 32
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.º 33
0
 public void SetWithIListShouldThrowArgumentNullException()
 {
     VectorF v = new VectorF(1);
       v.Set((IList<float>)null);
 }
        public SingularValueDecompositionF(MatrixF matrixA)
        {
            if (matrixA == null)
            {
                throw new ArgumentNullException("matrixA");
            }

            // Derived from LINPACK code.
            // Initialize.
            _m = matrixA.NumberOfRows;
            _n = matrixA.NumberOfColumns;
            MatrixF matrixAClone = matrixA.Clone();

            if (_m < _n)
            {
                throw new ArgumentException("The number of rows must be greater than or equal to the number of columns.", "matrixA");
            }

            int nu = Math.Min(_m, _n);

            _s = new VectorF(Math.Min(_m + 1, _n));
            _u = new MatrixF(_m, nu); //Jama getU() returns new Matrix(U,_m,Math.min(_m+1,_n)) ?!
            _v = new MatrixF(_n, _n);
            float[] e    = new float[_n];
            float[] work = new float[_m];

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

            // By default, we calculate U and V. To calculate only U or V we can set one of the following
            // two constants to false. (This optimization is not yet tested.)
            const bool wantu = true;
            const bool wantv = true;

            // Reduce A to bidiagonal form, storing the diagonal elements
            // in s and the super-diagonal elements in e.

            int nct = Math.Min(_m - 1, _n);
            int nrt = Math.Max(0, Math.Min(_n - 2, _m));

            for (int k = 0; k < 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] = MathHelper.Hypotenuse(_s[k], matrixAClone[i, k]);
                    }

                    if (_s[k] != 0)
                    {
                        if (matrixAClone[k, k] < 0)
                        {
                            _s[k] = -_s[k];
                        }

                        for (int i = k; i < _m; i++)
                        {
                            matrixAClone[i, k] /= _s[k];
                        }

                        matrixAClone[k, k] += 1;
                    }

                    _s[k] = -_s[k];
                }
                for (int j = k + 1; j < _n; j++)
                {
                    if ((k < nct) && (_s[k] != 0))
                    {
                        // Apply the transformation.
                        float t = 0;
                        for (int i = k; i < _m; i++)
                        {
                            t += matrixAClone[i, k] * matrixAClone[i, j];
                        }

                        t = -t / matrixAClone[k, k];
                        for (int i = k; i < _m; i++)
                        {
                            matrixAClone[i, j] += t * matrixAClone[i, k];
                        }
                    }

                    // Place the k-th row of A into e for the
                    // subsequent calculation of the row transformation.

                    e[j] = matrixAClone[k, j];
                }

                if (wantu & (k < nct))
                {
                    // Place the transformation in U for subsequent back
                    // multiplication.
                    for (int i = k; i < _m; i++)
                    {
                        _u[i, k] = matrixAClone[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] = MathHelper.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;
                        }

                        for (int j = k + 1; j < _n; j++)
                        {
                            for (int i = k + 1; i < _m; i++)
                            {
                                work[i] += e[j] * matrixAClone[i, j];
                            }
                        }

                        for (int j = k + 1; j < _n; j++)
                        {
                            float t = -e[j] / e[k + 1];
                            for (int i = k + 1; i < _m; i++)
                            {
                                matrixAClone[i, j] += 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 = Math.Min(_n, _m + 1);

            if (nct < _n)
            {
                _s[nct] = matrixAClone[nct, nct];
            }

            if (_m < p)
            {
                _s[p - 1] = 0;
            }

            if (nrt + 1 < p)
            {
                e[nrt] = matrixAClone[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)
                    {
                        for (int j = k + 1; j < nu; j++)
                        {
                            float t = 0;
                            for (int i = k; i < _m; i++)
                            {
                                t += _u[i, k] * _u[i, j];
                            }

                            t = -t / _u[k, k];
                            for (int i = k; i < _m; i++)
                            {
                                _u[i, j] += t * _u[i, k];
                            }
                        }
                        for (int i = k; i < _m; i++)
                        {
                            _u[i, k] = -_u[i, k];
                        }

                        _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.0))
                    {
                        for (int j = k + 1; j < nu; j++)
                        {
                            float t = 0;
                            for (int i = k + 1; i < _n; i++)
                            {
                                t += _v[i, k] * _v[i, j];
                            }

                            t = -t / _v[k + 1, k];
                            for (int i = k + 1; i < _n; i++)
                            {
                                _v[i, j] += t * _v[i, k];
                            }
                        }
                    }

                    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;
            double eps  = (float)Math.Pow(2, -23);  // 2^-52 for double
            double tiny = (float)Math.Pow(2, -100); // 2^-100 for float is an estimation by HelmutG

            // Original: 2^-966 for double
            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 (Math.Abs(e[k]) <= tiny + eps * (Math.Abs(_s[k]) + 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;
                        }

                        float t = (ks != p ? Math.Abs(e[ks]) : 0) + (ks != k + 1 ? Math.Abs(e[ks - 1]) : 0);
                        if (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:
                {
                    float f = e[p - 2];
                    e[p - 2] = 0;
                    for (int j = p - 2; j >= k; j--)
                    {
                        float t  = MathHelper.Hypotenuse(_s[j], f);
                        float cs = _s[j] / t;
                        float 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:
                {
                    float f = e[k - 1];
                    e[k - 1] = 0;
                    for (int j = k; j < p; j++)
                    {
                        float t  = MathHelper.Hypotenuse(_s[j], f);
                        float cs = _s[j] / t;
                        float 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.

                    float scale = Math.Max(Math.Max(Math.Max(Math.Max(
                                                                 Math.Abs(_s[p - 1]), Math.Abs(_s[p - 2])), Math.Abs(e[p - 2])),
                                                    Math.Abs(_s[k])), Math.Abs(e[k]));
                    float sp    = _s[p - 1] / scale;
                    float spm1  = _s[p - 2] / scale;
                    float epm1  = e[p - 2] / scale;
                    float sk    = _s[k] / scale;
                    float ek    = e[k] / scale;
                    float b     = ((spm1 + sp) * (spm1 - sp) + epm1 * epm1) / 2;
                    float c     = (sp * epm1) * (sp * epm1);
                    float shift = 0;
                    if ((b != 0.0) | (c != 0.0))
                    {
                        shift = (float)Math.Sqrt(b * b + c);
                        if (b < 0.0)
                        {
                            shift = -shift;
                        }

                        shift = c / (b + shift);
                    }
                    float f = (sk + sp) * (sk - sp) + shift;
                    float g = sk * ek;

                    // Chase zeros.

                    for (int j = k; j < p - 1; j++)
                    {
                        float t  = MathHelper.Hypotenuse(f, g);
                        float cs = f / t;
                        float 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)
                        {
                            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;
                            }
                        }

                        t         = MathHelper.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))
                        {
                            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;
                            }
                        }
                    }

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

                // Convergence.

                case 4:
                {
                    // Make the singular values positive.

                    if (_s[k] <= 0.0)
                    {
                        _s[k] = (_s[k] < 0.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;
                        }

                        float t = _s[k];
                        _s[k]     = _s[k + 1];
                        _s[k + 1] = t;
                        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;
                }
            }
        }