Exemple #1
0
        public static double Compute(Complex a, Complex b)
        {
            Complex temp = a * ComplexMath.Conjugate(a);

            temp += (b * ComplexMath.Conjugate(b));
            double ret = ComplexMath.Absolute(temp);

            return(System.Math.Sqrt(ret));
        }
Exemple #2
0
        public static float Compute(ComplexFloat a, ComplexFloat b)
        {
            ComplexFloat temp = a * ComplexMath.Conjugate(a);

            temp += (b * ComplexMath.Conjugate(b));
            float ret = ComplexMath.Absolute(temp);

            return((float)System.Math.Sqrt(ret));
        }
        public void SquareDecomp()
        {
            ComplexFloatMatrix a = new ComplexFloatMatrix(3);

            a[0, 0] = new ComplexFloat(1.1f, 1.1f);
            a[0, 1] = new ComplexFloat(2.2f, -2.2f);
            a[0, 2] = new ComplexFloat(3.3f, 3.3f);
            a[1, 0] = new ComplexFloat(4.4f, -4.4f);
            a[1, 1] = new ComplexFloat(5.5f, 5.5f);
            a[1, 2] = new ComplexFloat(6.6f, -6.6f);
            a[2, 0] = new ComplexFloat(7.7f, 7.7f);
            a[2, 1] = new ComplexFloat(8.8f, -8.8f);
            a[2, 2] = new ComplexFloat(9.9f, 9.9f);

            ComplexFloatQRDecomp qrd = new ComplexFloatQRDecomp(a);
            ComplexFloatMatrix   qq  = qrd.Q.GetConjugateTranspose() * qrd.Q;
            ComplexFloatMatrix   qr  = qrd.Q * qrd.R;
            ComplexFloatMatrix   I   = ComplexFloatMatrix.CreateIdentity(3);

            // determine the maximum relative error
            double MaxError = 0.0;

            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; i < 3; i++)
                {
                    double E = ComplexMath.Absolute((qq[i, j] - I[i, j]));
                    if (E > MaxError)
                    {
                        MaxError = E;
                    }
                }
            }

            Assert.IsTrue(MaxError < 1.0E-6);

            MaxError = 0.0;
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; i < 3; i++)
                {
                    double E = ComplexMath.Absolute((qr[i, j] - a[i, j]) / a[i, j]);
                    if (E > MaxError)
                    {
                        MaxError = E;
                    }
                }
            }

            Assert.IsTrue(MaxError < 2.4E-6);
        }
Exemple #4
0
        public static ComplexDoubleVector GenerateRow(IComplexDoubleMatrix A, int r, int c1, int c2)
        {
            int cu = c2 - c1 + 1;
            ComplexDoubleVector u = new ComplexDoubleVector(cu);

            for (int j = c1; j <= c2; j++)
            {
                u[j - c1] = A[r, j];
                A[r, j]   = Complex.Zero;
            }

            double norm = u.GetNorm();

            if (c1 == c2 || norm == 0)
            {
                A[r, c1] = new Complex(-u[0].Real, -u[0].Imag);
                u[0]     = System.Math.Sqrt(2);
                return(u);
            }

            Complex scale = new Complex(1 / norm);

            Complex t  = Complex.Zero;
            Complex t1 = Complex.Zero;

            if (u[0].Real != 0 || u[0].Imag != 0)
            {
                t     = u[0];
                t1    = ComplexMath.Conjugate(u[0]);
                t     = ComplexMath.Absolute(t);
                t     = t1 / t;
                scale = scale * t;
            }

            A[r, c1] = -Complex.One / scale;

            for (int j = 0; j < cu; j++)
            {
                u[j] *= scale;
            }

            u[0] = new Complex(u[0].Real + 1);
            double s = System.Math.Sqrt(1 / u[0].Real);

            for (int j = 0; j < cu; j++)
            {
                u[j] = new Complex(s * u[j].Real, -s * u[j].Imag);
            }
            return(u);
        }
Exemple #5
0
        ///<summary>Compute the Infinity Norm of this <c>ComplexFloatVector</c></summary>
        ///<returns><c>float</c> results from norm.</returns>
        public float GetInfinityNorm()
        {
            float ret = 0;

            for (int i = 0; i < data.Length; i++)
            {
                float tmp = ComplexMath.Absolute(data[i]);
                if (tmp > ret)
                {
                    ret = tmp;
                }
            }
            return(ret);
        }
Exemple #6
0
        public static ComplexFloatVector GenerateColumn(IComplexFloatMatrix A, int r1, int r2, int c)
        {
            int ru = r2 - r1 + 1;
            ComplexFloatVector u = new ComplexFloatVector(r2 - r1 + 1);

            for (int i = r1; i <= r2; i++)
            {
                u[i - r1] = A[i, c];
                A[i, c]   = ComplexFloat.Zero;
            }

            float norm = u.GetNorm();

            if (r1 == r2 || norm == 0)
            {
                A[r1, c] = new ComplexFloat(-u[0]);
                u[0]     = (float)System.Math.Sqrt(2);
                return(u);
            }

            ComplexFloat scale = new ComplexFloat(1 / norm, 0);

            ComplexFloat t  = ComplexFloat.Zero;
            ComplexFloat t1 = ComplexFloat.Zero;

            if (u[0].Real != 0 || u[0].Imag != 0)
            {
                t     = u[0];
                t1    = ComplexMath.Conjugate(u[0]);
                t     = ComplexMath.Absolute(t);
                t     = t1 / t;
                scale = scale * t;
            }

            A[r1, c] = -ComplexFloat.One / scale;

            for (int i = 0; i < ru; i++)
            {
                u[i] = u[i] * scale;
            }

            u[0] = new ComplexFloat(u[0].Real + 1, 0);
            float s = (float)System.Math.Sqrt(1 / u[0].Real);

            for (int i = 0; i < ru; i++)
            {
                u[i] = new ComplexFloat(s * u[i].Real, s * u[i].Imag);
            }
            return(u);
        }
        public void SquareDecomp()
        {
            ComplexDoubleMatrix a = new ComplexDoubleMatrix(3);

            a[0, 0] = new Complex(1.1, 1.1);
            a[0, 1] = new Complex(2.2, -2.2);
            a[0, 2] = new Complex(3.3, 3.3);
            a[1, 0] = new Complex(4.4, -4.4);
            a[1, 1] = new Complex(5.5, 5.5);
            a[1, 2] = new Complex(6.6, -6.6);
            a[2, 0] = new Complex(7.7, 7.7);
            a[2, 1] = new Complex(8.8, -8.8);
            a[2, 2] = new Complex(9.9, 9.9);

            ComplexDoubleQRDecomp qrd = new ComplexDoubleQRDecomp(a);
            ComplexDoubleMatrix   qq  = qrd.Q.GetConjugateTranspose() * qrd.Q;
            ComplexDoubleMatrix   qr  = qrd.Q * qrd.R;
            ComplexDoubleMatrix   I   = ComplexDoubleMatrix.CreateIdentity(3);

            // determine the maximum relative error
            double MaxError = 0.0;

            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; i < 3; i++)
                {
                    double E = ComplexMath.Absolute((qq[i, j] - I[i, j]));
                    if (E > MaxError)
                    {
                        MaxError = E;
                    }
                }
            }
            Assert.IsTrue(MaxError < 1.0E-14);

            MaxError = 0.0;
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; i < 3; i++)
                {
                    double E = ComplexMath.Absolute((qr[i, j] - a[i, j]) / a[i, j]);
                    if (E > MaxError)
                    {
                        MaxError = E;
                    }
                }
            }
            Assert.IsTrue(MaxError < 1.0E-14);
        }
Exemple #8
0
        ///<summary>Compute the P Norm of this <c>ComplexFloatVector</c></summary>
        ///<returns><c>float</c> results from norm.</returns>
        ///<remarks>p &gt; 0, if p &lt; 0, ABS(p) is used. If p = 0, the infinity norm is returned.</remarks>
        public float GetNorm(double p)
        {
            if (p == 0)
            {
                return(GetInfinityNorm());
            }
            if (p < 0)
            {
                p = -p;
            }
            double ret = 0;

            for (int i = 0; i < data.Length; i++)
            {
                ret += System.Math.Pow(ComplexMath.Absolute(data[i]), p);
            }
            return((float)System.Math.Pow(ret, 1 / p));
        }
        public void Test()
        {
            DoubleMatrix test = svd.U * svd.W * svd.V.GetTranspose();
            double       e;
            double       me = 0;

            for (int i = 0; i < test.RowLength; i++)
            {
                for (int j = 0; j < test.ColumnLength; j++)
                {
                    e = ComplexMath.Absolute((a[i, j] - test[i, j]) / a[i, j]);
                    if (e > me)
                    {
                        me = e;
                    }
                }
            }
            Assert.IsTrue(me < TOLERENCE, "Maximum Error = " + me.ToString());
        }
        public void WTest()
        {
            FloatMatrix test = wsvd.U * wsvd.W * wsvd.V.GetTranspose();
            float       e;
            float       me = 0;

            for (int i = 0; i < test.RowLength; i++)
            {
                for (int j = 0; j < test.ColumnLength; j++)
                {
                    e = ComplexMath.Absolute((wa[i, j] - test[i, j]) / wa[i, j]);
                    if (e > me)
                    {
                        me = e;
                    }
                }
            }
            Assert.IsTrue(me < TOLERENCE, "Maximum Error = " + me.ToString());
        }
Exemple #11
0
        internal static double Compute(int n, Complex[] X, int incx)
        {
            ArgumentCheck(n, X, X.Length, ref incx);

            double ret = 0;

#if MANAGED
            var temp = new Complex(0);
            int ix   = 0;
            for (int i = 0; i < n; ++i)
            {
                temp += (X[ix] * ComplexMath.Conjugate(X[ix]));
                ix   += incx;
            }
            ret = System.Math.Sqrt(ComplexMath.Absolute(temp));
#else
            ret = dna_blas_dznrm2(n, X, incx);
#endif
            return(ret);
        }
Exemple #12
0
        internal static float Compute(int n, ComplexFloat[] X, int incx)
        {
            ArgumentCheck(n, X, X.Length, ref incx);

            float ret = 0;

#if MANAGED
            ComplexFloat temp = new ComplexFloat(0);
            int          ix   = 0;
            for (int i = 0; i < n; ++i)
            {
                temp += (X[ix] * ComplexMath.Conjugate(X[ix]));
                ix   += incx;
            }
            ret = (float)System.Math.Sqrt(ComplexMath.Absolute(temp));
#else
            ret = dna_blas_scnrm2(n, X, incx);
#endif
            return(ret);
        }
        public void Absolute()
        {
            Complex      cd1 = new Complex(1.1, -2.2);
            Complex      cd2 = new Complex(0, -2.2);
            Complex      cd3 = new Complex(1.1, 0);
            Complex      cd4 = new Complex(-1.1, 2.2);
            ComplexFloat cf1 = new ComplexFloat(1.1f, -2.2f);
            ComplexFloat cf2 = new ComplexFloat(0, -2.2f);
            ComplexFloat cf3 = new ComplexFloat(1.1f, 0);
            ComplexFloat cf4 = new ComplexFloat(-1.1f, 2.2f);

            Assert.AreEqual(ComplexMath.Absolute(cd1), 2.460, TOLERENCE);
            Assert.AreEqual(ComplexMath.Absolute(cd2), 2.2, TOLERENCE);
            Assert.AreEqual(ComplexMath.Absolute(cd3), 1.1, TOLERENCE);
            Assert.AreEqual(ComplexMath.Absolute(cd4), 2.460, TOLERENCE);
            Assert.AreEqual(ComplexMath.Absolute(cf1), 2.460, TOLERENCE);
            Assert.AreEqual(ComplexMath.Absolute(cf2), 2.2, TOLERENCE);
            Assert.AreEqual(ComplexMath.Absolute(cf3), 1.1, TOLERENCE);
            Assert.AreEqual(ComplexMath.Absolute(cf4), 2.460, TOLERENCE);
        }
Exemple #14
0
        private static ComplexFloat csign(ComplexFloat z1, ComplexFloat z2)
        {
            ComplexFloat ret = ComplexMath.Absolute(z1) * (z2 / ComplexMath.Absolute(z2));

            return(ret);
        }
        /// <summary>Performs the LU factorization.</summary>
        protected override void InternalCompute()
        {
#if MANAGED
            factor = new ComplexDoubleMatrix(matrix).data;
            int m = matrix.RowLength;
            int n = matrix.ColumnLength;
            pivots = new int[m];
            for (int i = 0; i < m; i++)
            {
                pivots[i] = i;
            }
            sign = 1;
            Complex[] LUrowi;
            Complex[] LUcolj = new Complex[m];

            // Outer loop.
            for (int j = 0; j < n; j++)
            {
                // Make a copy of the j-th column to localize references.
                for (int i = 0; i < m; i++)
                {
                    LUcolj[i] = factor[i][j];
                }

                // Apply previous transformations.
                for (int i = 0; i < m; i++)
                {
                    LUrowi = factor[i];

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

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

                // Find pivot and exchange if necessary.
                int p = j;
                for (int i = j + 1; i < m; i++)
                {
                    if (ComplexMath.Absolute(LUcolj[i]) > ComplexMath.Absolute(LUcolj[p]))
                    {
                        p = i;
                    }
                }
                if (p != j)
                {
                    for (int k = 0; k < n; k++)
                    {
                        Complex t = factor[p][k];
                        factor[p][k] = factor[j][k];
                        factor[j][k] = t;
                    }
                    int r = pivots[p];
                    pivots[p] = pivots[j];
                    pivots[j] = r;
                    sign      = -sign;
                }

                // Compute multipliers.

                if (j < m & factor[j][j] != Complex.Zero)
                {
                    for (int i = j + 1; i < m; i++)
                    {
                        factor[i][j] /= factor[j][j];
                    }
                }
            }
#else
            factor = new Complex[matrix.data.Length];
            Array.Copy(matrix.data, factor, matrix.data.Length);
            Lapack.Getrf.Compute(order, order, factor, order, out pivots);
            GetSign();
#endif
            SetLU();

            this.singular = false;
            for (int j = 0; j < u.RowLength; j++)
            {
                if (u[j, j] == 0)
                {
                    this.singular = true;
                    break;
                }
            }
        }
        ///<summary>Computes the algorithm.</summary>
        protected override void InternalCompute()
        {
            rows = matrix.RowLength;
            cols = matrix.ColumnLength;
            int mm = System.Math.Min(rows + 1, cols);

            s = new DoubleVector(mm); // singular values

#if MANAGED
            // Derived from LINPACK code.
            // Initialize.

            u = new DoubleMatrix(rows, rows); // left vectors
            v = new DoubleMatrix(cols, cols); // right vectors
            DoubleVector e    = new DoubleVector(cols);
            DoubleVector work = new DoubleVector(rows);

            int    i, iter, j, k, kase, l, lp1, ls = 0, lu, m, nct, nctp1, ncu, nrt, nrtp1;
            double b, c, cs = 0.0, el, emm1, f, g, scale, shift, sl,
                   sm, sn = 0.0, smm1, t1, test, ztest, xnorm, enorm;
            double t, r;

            ncu = rows;

            //   reduce matrix to bidiagonal form, storing the diagonal elements
            //   in s and the super-diagonal elements in e.
            int info = 0;
            nct = System.Math.Min(rows - 1, cols);
            nrt = System.Math.Max(0, System.Math.Min(cols - 2, rows));
            lu  = System.Math.Max(nct, nrt);

            for (l = 0; l < lu; l++)
            {
                lp1 = l + 1;
                if (l < nct)
                {
                    // compute the transformation for the l-th column and
                    // place the l-th diagonal in s[l].
                    xnorm = dnrm2Column(matrix, l, l);
                    s[l]  = xnorm;
                    if (s[l] != 0.0)
                    {
                        if (matrix[l, l] != 0.0)
                        {
                            s[l] = dsign(s[l], matrix[l, l]);
                        }
                        dscalColumn(matrix, l, l, 1.0 / s[l]);
                        matrix[l, l] = 1.0 + matrix[l, l];
                    }

                    s[l] = -s[l];
                }

                for (j = lp1; j < cols; j++)
                {
                    if (l < nct)
                    {
                        if (s[l] != 0.0)
                        {
                            // apply the transformation.
                            t = -ddot(matrix, l, j, l) / matrix[l, l];
                            for (int ii = l; ii < matrix.RowLength; ii++)
                            {
                                matrix[ii, j] += t * matrix[ii, l];
                            }
                        }
                    }

                    //place the l-th row of matrix into  e for the
                    //subsequent calculation of the row transformation.
                    e[j] = matrix[l, j];
                }

                if (computeVectors && l < nct)
                {
                    // place the transformation in u for subsequent back multiplication.
                    for (i = l; i < rows; i++)
                    {
                        u[i, l] = matrix[i, l];
                    }
                }

                if (l < nrt)
                {
                    // compute the l-th row transformation and place the l-th super-diagonal in e(l).
                    enorm = dnrm2Vector(e, lp1);
                    e[l]  = enorm;
                    if (e[l] != 0.0)
                    {
                        if (e[lp1] != 0.0)
                        {
                            e[l] = dsign(e[l], e[lp1]);
                        }
                        dscalVector(e, lp1, 1.0 / e[l]);
                        e[lp1] = 1.0 + e[lp1];
                    }
                    e[l] = -e[l];

                    if (lp1 < rows && e[l] != 0.0)
                    {
                        // apply the transformation.
                        for (i = lp1; i < rows; i++)
                        {
                            work[i] = 0.0;
                        }

                        for (j = lp1; j < cols; j++)
                        {
                            for (int ii = lp1; ii < matrix.RowLength; ii++)
                            {
                                work[ii] += e[j] * matrix[ii, j];
                            }
                        }

                        for (j = lp1; j < cols; j++)
                        {
                            double ww = -e[j] / e[lp1];
                            for (int ii = lp1; ii < matrix.RowLength; ii++)
                            {
                                matrix[ii, j] += ww * work[ii];
                            }
                        }
                    }

                    if (computeVectors)
                    {
                        // place the transformation in v for subsequent back multiplication.
                        for (i = lp1; i < cols; i++)
                        {
                            v[i, l] = e[i];
                        }
                    }
                }
            }

            //   set up the final bidiagonal matrix or order m.
            m     = System.Math.Min(cols, rows + 1);
            nctp1 = nct + 1;
            nrtp1 = nrt + 1;
            if (nct < cols)
            {
                s[nctp1 - 1] = matrix[nctp1 - 1, nctp1 - 1];
            }
            if (rows < m)
            {
                s[m - 1] = 0.0;
            }
            if (nrtp1 < m)
            {
                e[nrtp1 - 1] = matrix[nrtp1 - 1, m - 1];
            }
            e[m - 1] = 0.0;

            //   if required, generate u.
            if (computeVectors)
            {
                for (j = nctp1 - 1; j < ncu; j++)
                {
                    for (i = 0; i < rows; i++)
                    {
                        u[i, j] = 0.0;
                    }
                    u[j, j] = 1.0;
                }

                for (l = nct - 1; l >= 0; l--)
                {
                    if (s[l] != 0.0)
                    {
                        for (j = l + 1; j < ncu; j++)
                        {
                            t = -ddot(u, l, j, l) / u[l, l];
                            for (int ii = l; ii < u.RowLength; ii++)
                            {
                                u[ii, j] += t * u[ii, l];
                            }
                        }
                        dscalColumn(u, l, l, -1.0);
                        u[l, l] = 1.0 + u[l, l];
                        for (i = 0; i < l; i++)
                        {
                            u[i, l] = 0.0;
                        }
                    }
                    else
                    {
                        for (i = 0; i < rows; i++)
                        {
                            u[i, l] = 0.0;
                        }
                        u[l, l] = 1.0;
                    }
                }
            }

            //   if it is required, generate v.
            if (computeVectors)
            {
                for (l = cols - 1; l >= 0; l--)
                {
                    lp1 = l + 1;
                    if (l < nrt)
                    {
                        if (e[l] != 0.0)
                        {
                            for (j = lp1; j < cols; j++)
                            {
                                t = -ddot(v, l, j, lp1) / v[lp1, l];
                                for (int ii = l; ii < v.RowLength; ii++)
                                {
                                    v[ii, j] += t * v[ii, l];
                                }
                            }
                        }
                    }
                    for (i = 0; i < cols; i++)
                    {
                        v[i, l] = 0.0;
                    }
                    v[l, l] = 1.0;
                }
            }

            //   transform s and e so that they are  double .
            for (i = 0; i < m; i++)
            {
                if (s[i] != 0.0)
                {
                    t    = s[i];
                    r    = s[i] / t;
                    s[i] = t;
                    if (i < m - 1)
                    {
                        e[i] = e[i] / r;
                    }
                    if (computeVectors)
                    {
                        dscalColumn(u, i, 0, r);
                    }
                }
                //   ...exit
                if (i == m - 1)
                {
                    break;
                }
                if (e[i] != 0.0)
                {
                    t        = e[i];
                    r        = t / e[i];
                    e[i]     = t;
                    s[i + 1] = s[i + 1] * r;
                    if (computeVectors)
                    {
                        dscalColumn(v, i + 1, 0, r);
                    }
                }
            }

            //   main iteration loop for the singular values.
            mm   = m;
            iter = 0;

            while (m > 0)
            { // quit if all the singular values have been found.
              // if too many iterations have been performed, set
              //      flag and return.
                if (iter >= MAXITER)
                {
                    info = m;
                    //   ......exit
                    break;
                }

                //      this section of the program inspects for
                //      negligible elements in the s and e arrays.  on
                //      completion the variables kase and l are set as follows.

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

                for (l = m - 2; l >= 0; l--)
                {
                    test  = ComplexMath.Absolute(s[l]) + ComplexMath.Absolute(s[l + 1]);
                    ztest = test + ComplexMath.Absolute(e[l]);
                    if (ztest == test)
                    {
                        e[l] = 0.0;
                        break;
                    }
                }

                if (l == m - 2)
                {
                    kase = 4;
                }
                else
                {
                    for (ls = m - 1; ls > l; ls--)
                    {
                        test = 0.0;
                        if (ls != m - 1)
                        {
                            test = test + ComplexMath.Absolute(e[ls]);
                        }
                        if (ls != l + 1)
                        {
                            test = test + ComplexMath.Absolute(e[ls - 1]);
                        }
                        ztest = test + ComplexMath.Absolute(s[ls]);
                        if (ztest == test)
                        {
                            s[ls] = 0.0;
                            break;
                        }
                    }

                    if (ls == l)
                    {
                        kase = 3;
                    }
                    else if (ls == m - 1)
                    {
                        kase = 1;
                    }
                    else
                    {
                        kase = 2;
                        l    = ls;
                    }
                }

                l = l + 1;

                //      perform the task indicated by kase.
                switch (kase)
                {
                // deflate negligible s[m].
                case 1:
                    f        = e[m - 2];
                    e[m - 2] = 0.0;
                    for (k = m - 2; k >= 0; k--)
                    {
                        t1 = s[k];
                        drotg(ref t1, ref f, ref cs, ref sn);
                        s[k] = t1;
                        if (k != l)
                        {
                            f        = -sn * e[k - 1];
                            e[k - 1] = cs * e[k - 1];
                        }
                        if (computeVectors)
                        {
                            drot(v, k, m - 1, cs, sn);
                        }
                    }
                    break;

                // split at negligible s[l].
                case 2:
                    f        = e[l - 1];
                    e[l - 1] = 0.0;
                    for (k = l; k < m; k++)
                    {
                        t1 = s[k];
                        drotg(ref t1, ref f, ref cs, ref sn);
                        s[k] = t1;
                        f    = -sn * e[k];
                        e[k] = cs * e[k];
                        if (computeVectors)
                        {
                            drot(u, k, l - 1, cs, sn);
                        }
                    }
                    break;

                // perform one qr step.
                case 3:
                    // calculate the shift.
                    scale = 0.0;
                    scale = System.Math.Max(scale, ComplexMath.Absolute(s[m - 1]));
                    scale = System.Math.Max(scale, ComplexMath.Absolute(s[m - 2]));
                    scale = System.Math.Max(scale, ComplexMath.Absolute(e[m - 2]));
                    scale = System.Math.Max(scale, ComplexMath.Absolute(s[l]));
                    scale = System.Math.Max(scale, ComplexMath.Absolute(e[l]));
                    sm    = s[m - 1] / scale;
                    smm1  = s[m - 2] / scale;
                    emm1  = e[m - 2] / scale;
                    sl    = s[l] / scale;
                    el    = e[l] / scale;
                    b     = ((smm1 + sm) * (smm1 - sm) + emm1 * emm1) / 2.0;
                    c     = (sm * emm1) * (sm * emm1);
                    shift = 0.0;
                    if (b != 0.0 || c != 0.0)
                    {
                        shift = System.Math.Sqrt(b * b + c);
                        if (b < 0.0)
                        {
                            shift = -shift;
                        }
                        shift = c / (b + shift);
                    }
                    f = (sl + sm) * (sl - sm) + shift;
                    g = sl * el;

                    // chase zeros.
                    for (k = l; k < m - 1; k++)
                    {
                        drotg(ref f, ref g, ref cs, ref sn);
                        if (k != l)
                        {
                            e[k - 1] = f;
                        }
                        f        = cs * s[k] + sn * e[k];
                        e[k]     = cs * e[k] - sn * s[k];
                        g        = sn * s[k + 1];
                        s[k + 1] = cs * s[k + 1];
                        if (computeVectors)
                        {
                            drot(v, k, k + 1, cs, sn);
                        }
                        drotg(ref f, ref g, ref cs, ref sn);
                        s[k]     = f;
                        f        = cs * e[k] + sn * s[k + 1];
                        s[k + 1] = -sn * e[k] + cs * s[k + 1];
                        g        = sn * e[k + 1];
                        e[k + 1] = cs * e[k + 1];
                        if (computeVectors && k < rows)
                        {
                            drot(u, k, k + 1, cs, sn);
                        }
                    }
                    e[m - 2] = f;
                    iter     = iter + 1;
                    break;

                // convergence.
                case 4:
                    // make the singular value  positive
                    if (s[l] < 0.0)
                    {
                        s[l] = -s[l];
                        if (computeVectors)
                        {
                            dscalColumn(v, l, 0, -1.0);
                        }
                    }

                    // order the singular value.
                    while (l != mm - 1)
                    {
                        if (s[l] >= s[l + 1])
                        {
                            break;
                        }
                        t        = s[l];
                        s[l]     = s[l + 1];
                        s[l + 1] = t;
                        if (computeVectors && l < cols)
                        {
                            dswap(v, l, l + 1);
                        }
                        if (computeVectors && l < rows)
                        {
                            dswap(u, l, l + 1);
                        }
                        l = l + 1;
                    }
                    iter = 0;
                    m    = m - 1;
                    break;
                }
            }

            // make matrix w from vector s
            // there is no constructor, creating diagonal matrix from vector
            // doing it ourselves
            mm = System.Math.Min(matrix.RowLength, matrix.ColumnLength);
#else
            u = new DoubleMatrix(rows);
            v = new DoubleMatrix(cols);
            double[] a = new double[matrix.data.Length];
            Array.Copy(matrix.data, a, matrix.data.Length);
            Lapack.Gesvd.Compute(rows, cols, a, s.data, u.data, v.data);
            v.Transpose();
#endif
            w = new DoubleMatrix(matrix.RowLength, matrix.ColumnLength);
            for (int ii = 0; ii < matrix.RowLength; ii++)
            {
                for (int jj = 0; jj < matrix.ColumnLength; jj++)
                {
                    if (ii == jj)
                    {
                        w[ii, ii] = s[ii];
                    }
                }
            }

            double eps = System.Math.Pow(2.0, -52.0);
            double tol = System.Math.Max(matrix.RowLength, matrix.ColumnLength) * s[0] * eps;
            rank = 0;

            for (int h = 0; h < mm; h++)
            {
                if (s[h] > tol)
                {
                    rank++;
                }
            }

            if (!computeVectors)
            {
                u = null;
                v = null;
            }
            matrix = null;
        }
        private static Complex csign(Complex z1, Complex z2)
        {
            Complex ret = ComplexMath.Absolute(z1) * (z2 / ComplexMath.Absolute(z2));

            return(ret);
        }