Beispiel #1
0
            public void set_large_dimension_throws()
            {
                var v = new VectorD(5);

                Assert.Throws <ArgumentOutOfRangeException>(() => v.Set(5, 0.0));
                Assert.Throws <ArgumentOutOfRangeException>(() => v.Set(6, 0.0));
                Assert.Throws <ArgumentOutOfRangeException>(() => v.Set(101, 0.0));
                Assert.Throws <ArgumentOutOfRangeException>(() => v.Set(int.MaxValue, 0.0));
            }
Beispiel #2
0
            public void set_negative_dimension_throws()
            {
                var v = new VectorD(5);

                Assert.Throws <ArgumentOutOfRangeException>(() => v.Set(-1, 0.0));
                Assert.Throws <ArgumentOutOfRangeException>(() => v.Set(-4, 0.0));
                Assert.Throws <ArgumentOutOfRangeException>(() => v.Set(-5, 0.0));
                Assert.Throws <ArgumentOutOfRangeException>(() => v.Set(int.MinValue, 0.0));
            }
Beispiel #3
0
            public void source_vector_is_unchanged()
            {
                var actual = new VectorD(2);

                actual.Set(0, 4.5);
                actual.Set(1, 888);
                var expected = new VectorD(actual);

                var result = actual.GetQuotient(2);

                Assert.Equal(expected, actual);
            }
Beispiel #4
0
            public void can_set_componenets()
            {
                var v = new VectorD(new[] { 2.0, 6.0, 7.0 });

                v.Set(0, 3.0);
                v.Set(1, 4.0);
                v.Set(2, 5.0);

                Assert.Equal(3.0, v.Get(0));
                Assert.Equal(4.0, v.Get(1));
                Assert.Equal(5.0, v.Get(2));
            }
Beispiel #5
0
            public void can_get_magnitude_squared()
            {
                var vector = new VectorD(3);

                vector.Set(0, 3);
                vector.Set(1, -4);
                vector.Set(2, 5);
                var expected = 50.0;

                var actual = vector.GetMagnitudeSquared();

                Assert.Equal(expected, actual);
            }
Beispiel #6
0
            public void same_vector_reference_has_same_hashcode_when_changed()
            {
                var m = new VectorD(2);

                m.Set(0, 9);
                m.Set(1, -8);
                var expectedHashCode = m.GetHashCode();

                m.Set(0, 4);
                m.Set(1, 19);

                Assert.Equal(expectedHashCode, m.GetHashCode());
            }
Beispiel #7
0
            public void source_vector_is_unchanged()
            {
                var actual = new VectorD(3);

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

                var result = actual.GetScaled(2);

                Assert.Equal(expected, actual);
            }
Beispiel #8
0
            public void can_get_magnitude()
            {
                var vector = new VectorD(3);

                vector.Set(0, 3);
                vector.Set(1, -4);
                vector.Set(2, 5);
                var expected = Math.Sqrt(50.0);

                var actual = vector.GetMagnitude();

                Assert.Equal(expected, actual);
            }
Beispiel #9
0
            public void negative_values_produce_same_magnitude()
            {
                var vector = new VectorD(3);

                vector.Set(0, 3);
                vector.Set(1, -4);
                vector.Set(2, 5);
                var expected = vector.GetMagnitude();

                var actual = vector.GetNegative().GetMagnitude();

                Assert.Equal(expected, actual);
            }
Beispiel #10
0
            public void different_ref_same_components_are_equal()
            {
                var a = new VectorD(2);

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

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

                Assert.True(a.Equals((object)b));
                Assert.True(b.Equals((object)a));
            }
Beispiel #11
0
            public void different_components_are_not_equal()
            {
                var a = new VectorD(2);

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

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

                Assert.False(a.Equals(b));
                Assert.False(b.Equals(a));
            }
Beispiel #12
0
            public void different_sizes_are_not_equal()
            {
                var a = new VectorD(2);

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

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

                Assert.False(a.Equals((object)b));
                Assert.False(b.Equals((object)a));
            }
Beispiel #13
0
            public void can_get_negative_vector()
            {
                var source = new VectorD(2);

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

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

                var actual = source.GetNegative();

                Assert.Equal(expected, actual);
            }
Beispiel #14
0
            public void copy_constructor_copies_all_componenets()
            {
                var expected = new VectorD(5);

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

                var actual = new VectorD(expected);

                Assert.NotSame(expected, actual);
                Assert.Equal(expected, actual);
            }
Beispiel #15
0
            public void can_divide_vector()
            {
                var actual = new VectorD(2);

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

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

                actual.Divide(4);

                Assert.Equal(expected, actual);
            }
Beispiel #16
0
            public void can_negate()
            {
                var actual = new VectorD(2);

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

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

                actual.Negate();

                Assert.Equal(expected, actual);
            }
Beispiel #17
0
            public void example_1()
            {
                var left = new VectorD(5);

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

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

                var actual = left.GetAngleBetween(right);

                Assert.Equal(expected, actual, 10);
            }
Beispiel #18
0
            public void can_get_quotient_vector()
            {
                var source = new VectorD(2);

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

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

                var actual = source.GetQuotient(4);

                Assert.Equal(expected, actual);
            }
Beispiel #19
0
            public void array_constructor_assigns_componenets_and_length()
            {
                var components = new double[] { 4, 5, 6, 7 };
                var expected   = new VectorD(4);

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

                var actual = new VectorD(components);

                Assert.Equal(components.Length, actual.Dimensions);
                Assert.Equal(expected, actual);
            }
Beispiel #20
0
            public void get_all_element_for_dim_5()
            {
                var v = new VectorD(5);

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

                Assert.Equal(-1.0, v.Get(0));
                Assert.Equal(5.7, v.Get(1));
                Assert.Equal(-0.4, v.Get(2));
                Assert.Equal(9.0, v.Get(3));
                Assert.Equal(-101.1, v.Get(4));
            }
Beispiel #21
0
            public void right_angle_is_half_pi()
            {
                var left = new VectorD(4);

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

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

                var actual = left.GetAngleBetween(right);

                Assert.Equal(expected, actual, 10);
            }
Beispiel #22
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 EigenvalueDecompositionD(MatrixD 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 VectorD(_n);
            _e = new VectorD(_n);

            _isSymmetric = matrixA.IsSymmetric;

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

                // Tridiagonalize.
                ReduceToTridiagonal();

                // Diagonalize.
                TridiagonalToQL();
            }
            else
            {
                _v = new MatrixD(_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(double.NaN);
                            _v.Set(double.NaN);
                            _d.Set(double.NaN);
                            return;
                        }
                    }
                }

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

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

                // Reduce Hessenberg to real Schur form.
                HessenbergToRealSchur(matrixH);
            }
        }
Beispiel #23
0
            public void array_constructor_copies_all_componenets()
            {
                var arrayValues = new[] { 1.0, 2.0, 3.0 };
                var expected    = new VectorD(3);

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

                var actual = new VectorD(arrayValues);

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

                Assert.Equal(expected, actual);
            }
Beispiel #24
0
            public void can_get_scaled_vector()
            {
                var actual = new VectorD(3);

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

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

                actual.Scale(3);

                Assert.Equal(expected, actual);
            }
Beispiel #25
0
            public void can_get_scaled_vector()
            {
                var source = new VectorD(3);

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

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

                var actual = source.GetScaled(3);

                Assert.Equal(expected, actual);
            }
Beispiel #26
0
            public void subtracting_vectors_leaves_right_unchanged()
            {
                var left = new VectorD(3);

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

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

                left.Subtract(right);

                Assert.Equal(expectedRight, right);
            }
Beispiel #27
0
            public void can_get_dot()
            {
                var left = new VectorD(3);

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

                right.Set(0, -1.1);
                right.Set(1, 6.7);
                right.Set(2, 3.3);
                var expected = (1.2 * -1.1) + (3.0 * 6.7) + (-9.0 * 3.3);

                var actual = left.GetDot(right);

                Assert.Equal(expected, actual);
            }
Beispiel #28
0
            public void can_find_distance_in_both_directions()
            {
                var a = new VectorD(5);

                a.Set(0, 1);
                a.Set(1, 2);
                a.Set(2, 3);
                var b = new VectorD(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);
            }
Beispiel #29
0
            public void can_create_axis_unit_vector(int size, int dimension)
            {
                var expected = new VectorD(size);

                expected.Set(dimension, 1.0);

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

                Assert.Equal(expected, actual);
            }
Beispiel #30
0
            public void can_find_distance()
            {
                var a = new VectorD(5);

                a.Set(0, 1);
                a.Set(1, 2);
                a.Set(2, 3);
                var b = new VectorD(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);
            }
Beispiel #31
0
        public void ProjectTo2()
        {
            VectorD unitX = new VectorD(new double[] { 1, 0, 0, 0 });
              VectorD unitY = new VectorD(new double[] { 0, 1, 0, 0 });
              VectorD unitZ = new VectorD(new double[] { 0, 0, 1, 0 });
              VectorD one = new VectorD(new double[] { 1, 1, 1, 1 });

              // Project (1, 1, 1) to axes
              VectorD projection = new VectorD(new double[] { 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)
              VectorD expected = new VectorD(new double[] { 1, 1, 1, 0 }) / 3.0;
              projection.Set(unitX);
              projection.ProjectTo(new VectorD(new double[] { 1, 1, 1, 0 }));
              Assert.AreEqual(expected, projection);
              projection.Set(unitY);
              projection.ProjectTo(new VectorD(new double[] { 1, 1, 1, 0 }));
              Assert.AreEqual(expected, projection);
              projection.Set(unitZ);
              projection.ProjectTo(new VectorD(new double[] { 1, 1, 1, 0 }));
              Assert.AreEqual(expected, projection);
        }
Beispiel #32
0
 public void SetWithArrayShouldThrowArgumentNullException()
 {
     VectorD v = new VectorD(1);
       v.Set((double[])null);
 }
        //--------------------------------------------------------------
        /// <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 EigenvalueDecompositionD(MatrixD 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 VectorD(_n);
              _e = new VectorD(_n);

              _isSymmetric = matrixA.IsSymmetric;

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

            // Tridiagonalize.
            ReduceToTridiagonal();

            // Diagonalize.
            TridiagonalToQL();
              }
              else
              {
            _v = new MatrixD(_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(double.NaN);
              _v.Set(double.NaN);
              _d.Set(double.NaN);
              return;
            }
              }
            }

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

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

            // Reduce Hessenberg to real Schur form.
            HessenbergToRealSchur(matrixH);
              }
        }
Beispiel #34
0
        public void Set()
        {
            VectorD v = new VectorD(5);
              v.Set(0.123);
              Assert.AreEqual(5, v.NumberOfElements);
              for (int i = 0; i < 5; i++)
            Assert.AreEqual(0.123, v[i]);

              v.Set(new VectorD(new double[] { 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 double[] { 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<double>(new double[] { 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]);
        }
        public SingularValueDecompositionD(MatrixD matrixA)
        {
            if (matrixA == null)
            throw new ArgumentNullException("matrixA");

              // Derived from LINPACK code.
              // Initialize.
              _m = matrixA.NumberOfRows;
              _n = matrixA.NumberOfColumns;
              MatrixD 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 VectorD(Math.Min(_m + 1, _n));
              _u = new MatrixD(_m, nu);     //Jama getU() returns new Matrix(U,_m,Math.min(_m+1,_n)) ?!
              _v = new MatrixD(_n, _n);
              double[] e = new double[_n];
              double[] work = new double[_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(double.NaN);
            _v.Set(double.NaN);
            _s.Set(double.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.
            double 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++)
            {
              double 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++)
            {
              double 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++)
            {
              double 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 = Math.Pow(2, -52);
              double tiny = Math.Pow(2, -966);   // 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;

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

              double 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]));
              double sp = _s[p - 1] / scale;
              double spm1 = _s[p - 2] / scale;
              double epm1 = e[p - 2] / scale;
              double sk = _s[k] / scale;
              double ek = e[k] / scale;
              double b = ((spm1 + sp) * (spm1 - sp) + epm1 * epm1) / 2;
              double c = (sp * epm1) * (sp * epm1);
              double shift = 0;
              if ((b != 0.0) | (c != 0.0))
              {
                shift = Math.Sqrt(b * b + c);
                if (b < 0.0)
                  shift = -shift;

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

              // Chase zeros.

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

                double 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;
            }
              }
        }
Beispiel #36
0
 public void SetWithIListShouldThrowArgumentNullException()
 {
     var v = new VectorD(1);
       v.Set((IList<double>)null);
 }