示例#1
0
文件: Gerc.cs 项目: olesar/Altaxo
        internal static void Compute(Order order, int m, int n, Complex alpha, Complex[] X, int incx, Complex[] Y, int incy, Complex[] A, int lda)
        {
            ArgumentCheck(order, m, n, X, X.Length, ref incx, Y, Y.Length, ref incy, A, A.Length, lda);

#if MANAGED
            Complex temp;
            if (order == Order.RowMajor)
            {
                for (int i = 0, ix = 0; i < m; ++i, ix += incx)
                {
                    temp = alpha * X[ix];
                    for (int j = 0, jy = 0; j < n; ++j, jy += incy)
                    {
                        A[i * lda + j] += temp * ComplexMath.Conjugate(Y[jy]);
                    }
                }
            }
            else
            {
                for (int j = 0, jy = 0; j < n; ++j, jy += incy)
                {
                    temp = alpha * ComplexMath.Conjugate(Y[jy]);
                    for (int i = 0, ix = 0; i < m; ++i, ix += incx)
                    {
                        A[lda * j + i] += temp * X[ix];
                    }
                }
            }
#else
            dna_blas_zgerc(order, m, n, ref alpha, X, incx, Y, incy, A, lda);
#endif
        }
示例#2
0
        ///<summary>Calculates the inverse of the matrix.</summary>
        ///<returns>the inverse of the matrix.</returns>
        ///<exception cref="NotPositiveDefiniteException">A is not positive definite.</exception>
        public ComplexDoubleMatrix GetInverse()
        {
            Compute();
            if (!ispd)
            {
                throw new NotPositiveDefiniteException();
            }
            else
            {
#if MANAGED
                var ret = ComplexDoubleMatrix.CreateIdentity(order);
                ret = Solve(ret);
                return(ret);
#else
                Complex[] inverse = new Complex[l.data.Length];
                Array.Copy(l.data, inverse, l.data.Length);
                Lapack.Potri.Compute(Lapack.UpLo.Lower, order, inverse, order);
                ComplexDoubleMatrix ret = new ComplexDoubleMatrix(order, order);
                ret.data = inverse;
                for (int i = 0; i < order; i++)
                {
                    for (int j = 0; j < order; j++)
                    {
                        if (j > i)
                        {
                            ret.data[j * order + i] = ComplexMath.Conjugate(ret.data[i * order + j]);
                        }
                    }
                }
                return(ret);
#endif
            }
        }
示例#3
0
        internal static void Compute(Order order, Transpose transA, int m, int n, int kl, int ku, Complex alpha, Complex[] A, int lda, Complex[] X, int incx, Complex beta, Complex[] Y, int incy)
        {
            ArgumentCheck(order, transA, ku + kl + 1, m, n, A, A.Length, lda, X, X.Length, ref incx, Y, Y.Length, ref incy);
            if (alpha == Complex.Zero && beta == Complex.One)
            {
                return;
            }

#if MANAGED
            if ((order == Order.RowMajor && transA == Transpose.NoTrans) || (order == Order.ColumnMajor && transA != Transpose.NoTrans))
            {
                for (int i = 0; i < m; ++i)
                {
                    Y[i * incy] *= beta;
                    for (int j = 0; j < ku + kl + 1; ++j)
                    {
                        Y[i * incy] += alpha * A[j + i * lda] * X[(System.Math.Max(i - kl, 0) + j) * incx];
                    }
                }
            }
            else if (order == Order.RowMajor && transA == Transpose.ConjTrans)
            {
                for (int i = 0; i < m; ++i)
                {
                    Y[i * incy] *= beta;
                    for (int j = 0; j < ku + kl + 1; ++j)
                    {
                        Y[i * incy] += alpha * ComplexMath.Conjugate(A[j + i * lda]) * X[(System.Math.Max(i - kl, 0) + j) * incx];
                    }
                }
            }
            else if (order == Order.ColumnMajor && transA == Transpose.ConjTrans)
            {
                for (int i = 0; i < System.Math.Min(m, n); ++i)
                {
                    int ti = i * incy;
                    Y[ti] *= beta;
                    for (int k = -System.Math.Min(i, kl); k <= System.Math.Min(m - 1 - i, ku); ++k)
                    {
                        Y[ti] += alpha * ComplexMath.Conjugate(A[(i + k) * lda + ku - k]) * X[incx * (i + k)];
                    }
                }
            }
            else
            { // corresponds to the case ( (colMajor && noTranspose) || (rowMajor && transpose)) - no conjugates here
                for (int i = 0; i < System.Math.Min(m, n); ++i)
                {
                    int ti = i * incy;
                    Y[ti] *= beta;
                    for (int k = -System.Math.Min(i, kl); k <= System.Math.Min(m - 1 - i, ku); ++k)
                    {
                        Y[ti] += alpha * A[(i + k) * lda + ku - k] * X[incx * (i + k)];
                    }
                }
            }
#else
            dna_blas_zgbmv(order, transA, m, n, kl, ku, ref alpha, A, lda, X, incx, ref beta, Y, incy);
#endif
        }
示例#4
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));
        }
示例#5
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));
        }
示例#6
0
        ///<summary>Solves a system on linear equations, AX=B, where A is the factored matrixed.</summary>
        ///<param name="B">RHS side of the system.</param>
        ///<returns>the solution matrix, X.</returns>
        ///<exception cref="ArgumentNullException">B is null.</exception>
        ///<exception cref="NotPositiveDefiniteException">A is not positive definite.</exception>
        ///<exception cref="ArgumentException">The number of rows of A and B must be the same.</exception>
        public ComplexDoubleMatrix Solve(IROComplexDoubleMatrix B)
        {
            if (B == null)
            {
                throw new System.ArgumentNullException("B cannot be null.");
            }
            Compute();
            if (!ispd)
            {
                throw new NotPositiveDefiniteException();
            }
            else
            {
                if (B.Rows != order)
                {
                    throw new System.ArgumentException("Matrix row dimensions must agree.");
                }
#if MANAGED
                // Copy right hand side.
                int cols = B.Columns;
                var X    = new ComplexDoubleMatrix(B);
                for (int c = 0; c < cols; c++)
                {
                    // Solve L*Y = B;
                    for (int i = 0; i < order; i++)
                    {
                        Complex sum = B[i, c];
                        for (int k = i - 1; k >= 0; k--)
                        {
                            sum -= l.data[i][k] * X.data[k][c];
                        }
                        X.data[i][c] = sum / l.data[i][i];
                    }

                    // Solve L'*X = Y;
                    for (int i = order - 1; i >= 0; i--)
                    {
                        Complex sum = X.data[i][c];
                        for (int k = i + 1; k < order; k++)
                        {
                            sum -= ComplexMath.Conjugate(l.data[k][i]) * X.data[k][c];
                        }
                        X.data[i][c] = sum / ComplexMath.Conjugate(l.data[i][i]);
                    }
                }

                return(X);
#else
                Complex[] rhs = ComplexDoubleMatrix.ToLinearComplexArray(B);
                Lapack.Potrs.Compute(Lapack.UpLo.Lower, order, B.Columns, l.data, order, rhs, B.Rows);
                ComplexDoubleMatrix ret = new ComplexDoubleMatrix(order, B.Columns);
                ret.data = rhs;
                return(ret);
#endif
            }
        }
        private static Complex zdotc(ComplexDoubleMatrix A, int Col1, int Col2, int Start)
        {
            Complex z = Complex.Zero;

            for (int i = Start; i < A.RowLength; i++)
            {
                z += A[i, Col2] * ComplexMath.Conjugate(A[i, Col1]);
            }
            return(z);
        }
示例#8
0
        ///<summary>Computes the algorithm.</summary>
        protected override void InternalCompute()
        {
#if MANAGED
            l = new ComplexDoubleMatrix(matrix);
            for (int j = 0; j < order; j++)
            {
                Complex[] rowj = l.data[j];
                double    d    = 0.0;
                for (int k = 0; k < j; k++)
                {
                    Complex[] rowk = l.data[k];
                    Complex   s    = Complex.Zero;
                    for (int i = 0; i < k; i++)
                    {
                        s += rowk[i] * rowj[i];
                    }
                    rowj[k] = s = (matrix.data[j][k] - s) / l.data[k][k];
                    d       = d + (s * ComplexMath.Conjugate(s)).Real;
                }
                d = matrix.data[j][j].Real - d;
                if (d <= 0.0)
                {
                    ispd = false;
                    return;
                }
                l.data[j][j] = new Complex(System.Math.Sqrt(d));
                for (int k = j + 1; k < order; k++)
                {
                    l.data[j][k] = Complex.Zero;
                }
            }
#else
            Complex[] factor = new Complex[matrix.data.Length];
            Array.Copy(matrix.data, factor, matrix.data.Length);
            int status = Lapack.Potrf.Compute(Lapack.UpLo.Lower, order, factor, order);
            if (status != 0)
            {
                ispd = false;
            }
            l      = new ComplexDoubleMatrix(order);
            l.data = factor;
            for (int i = 0; i < order; i++)
            {
                for (int j = 0; j < order; j++)
                {
                    if (j > i)
                    {
                        l.data[j * order + i] = 0;
                    }
                }
            }
#endif
        }
        private static double dznrm2Column(ComplexDoubleMatrix A, int Col, int Start)
        {
            //  dznrm2Column returns the euclidean norm of a vector,
            // which is a part of column Col in matrix A, beginning from Start to end of column
            // so that dznrm2Column := sqrt( conjg( matrix' )*matrix )
            double s = 0;

            for (int i = Start; i < A.RowLength; i++)
            {
                s += (A[i, Col] * ComplexMath.Conjugate(A[i, Col])).Real;
            }
            return(System.Math.Sqrt(s));
        }
        private static double dznrm2Vector(ComplexDoubleVector A, int Start)
        {
            //  dznrm2Vector returns the euclidean norm of a vector,
            // which is a part of A, beginning from Start to end of vector
            // so that dznrm2Vector := sqrt( conjg( matrix' )*matrix )
            double s = 0;

            for (int i = Start; i < A.Length; i++)
            {
                s += (A[i] * ComplexMath.Conjugate(A[i])).Real;
            }
            return(System.Math.Sqrt(s));
        }
示例#11
0
        ///<summary>Solves a system on linear equations, AX=B, where A is the factored matrixed.</summary>
        ///<param name="B">RHS side of the system.</param>
        ///<returns>the solution vector, X.</returns>
        ///<exception cref="ArgumentNullException">B is null.</exception>
        ///<exception cref="NotPositiveDefiniteException">A is not positive definite.</exception>
        ///<exception cref="ArgumentException">The number of rows of A and the length of B must be the same.</exception>
        public ComplexDoubleVector Solve(IROComplexDoubleVector B)
        {
            if (B == null)
            {
                throw new System.ArgumentNullException("B cannot be null.");
            }
            Compute();
            if (!ispd)
            {
                throw new NotPositiveDefiniteException();
            }
            else
            {
                if (B.Length != order)
                {
                    throw new System.ArgumentException("The length of B must be the same as the order of the matrix.");
                }
#if MANAGED
                // Copy right hand side.
                var X = new ComplexDoubleVector(B);
                // Solve L*Y = B;
                for (int i = 0; i < order; i++)
                {
                    Complex sum = B[i];
                    for (int k = i - 1; k >= 0; k--)
                    {
                        sum -= l.data[i][k] * X.data[k];
                    }
                    X.data[i] = sum / l.data[i][i];
                }
                // Solve L'*X = Y;
                for (int i = order - 1; i >= 0; i--)
                {
                    Complex sum = X.data[i];
                    for (int k = i + 1; k < order; k++)
                    {
                        sum -= ComplexMath.Conjugate(l.data[k][i]) * X.data[k];
                    }
                    X.data[i] = sum / ComplexMath.Conjugate(l.data[i][i]);
                }

                return(X);
#else
                Complex[] rhs = ComplexDoubleMatrix.ToLinearComplexArray(B);
                Lapack.Potrs.Compute(Lapack.UpLo.Lower, order, 1, l.data, order, rhs, B.Length);
                ComplexDoubleVector ret = new ComplexDoubleVector(order, B.Length);
                ret.data = rhs;
                return(ret);
#endif
            }
        }
示例#12
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);
        }
示例#13
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);
        }
示例#14
0
        public void Conjugate()
        {
            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.Conjugate(cd1), new Complex(1.1, 2.2));
            Assert.AreEqual(ComplexMath.Conjugate(cd2), new Complex(0, 2.2));
            Assert.AreEqual(ComplexMath.Conjugate(cd3), new Complex(1.1, 0));
            Assert.AreEqual(ComplexMath.Conjugate(cd4), new Complex(-1.1, -2.2));
            Assert.AreEqual(ComplexMath.Conjugate(cf1), new ComplexFloat(1.1f, 2.2f));
            Assert.AreEqual(ComplexMath.Conjugate(cf2), new ComplexFloat(0, 2.2f));
            Assert.AreEqual(ComplexMath.Conjugate(cf3), new ComplexFloat(1.1f, 0));
            Assert.AreEqual(ComplexMath.Conjugate(cf4), new ComplexFloat(-1.1f, -2.2f));
        }
示例#15
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);
        }
示例#16
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);
        }
示例#17
0
        ///<summary>Compute the function of this class</summary>

        internal static ComplexFloat Compute(int n, ComplexFloat[] X, int incx, ComplexFloat[] Y, int incy)
        {
            if (n < 0)
            {
                return(ComplexFloat.Zero);
            }
            ArgumentCheck(n, X, X.Length, ref incx, Y, Y.Length, ref incy);

            ComplexFloat ret = new ComplexFloat(0);

#if MANAGED
            int ix = 0;
            int iy = 0;
            for (int i = 0; i < n; ++i)
            {
                ret += (ComplexMath.Conjugate(X[ix]) * Y[iy]);
                ix  += incx;
                iy  += incy;
            }
#else
            dna_blas_cdotc(n, X, incx, Y, incy, ref ret);
#endif
            return(ret);
        }
示例#18
0
        /// <summary>Finds the least squares solution of <c>A*X = B</c>, where <c>m &gt;= n</c></summary>
        /// <param name="B">A matrix with as many rows as A and any number of columns.</param>
        /// <returns>X that minimizes the two norm of <c>Q*R*X-B</c>.</returns>
        /// <exception cref="ArgumentException">Matrix row dimensions must agree.</exception>
        /// <exception cref="InvalidOperationException">Matrix is rank deficient or <c>m &lt; n</c>.</exception>
        public ComplexDoubleMatrix Solve(ComplexDoubleMatrix B)
        {
            if (B.RowLength != matrix.Rows)
            {
                throw new ArgumentException("Matrix row dimensions must agree.");
            }
            if (matrix.Rows < matrix.Columns)
            {
                throw new System.InvalidOperationException("A must have at lest as a many rows as columns.");
            }
            Compute();
            if (!this.isFullRank)
            {
                throw new System.InvalidOperationException("Matrix is rank deficient.");
            }

            // Copy right hand side
            int m  = matrix.Rows;
            int n  = matrix.Columns;
            int nx = B.ColumnLength;
            ComplexDoubleMatrix ret = new ComplexDoubleMatrix(n, nx);

#if MANAGED
            ComplexDoubleMatrix X = new ComplexDoubleMatrix(B);
            // Compute Y = transpose(Q)*B
            Complex[] column = new Complex[q_.RowLength];
            for (int j = 0; j < nx; j++)
            {
                for (int k = 0; k < m; k++)
                {
                    column[k] = X.data[k][j];
                }
                for (int i = 0; i < m; i++)
                {
                    Complex s = Complex.Zero;
                    for (int k = 0; k < m; k++)
                    {
                        s += ComplexMath.Conjugate(q_.data[k][i]) * column[k];
                    }
                    X.data[i][j] = s;
                }
            }

            // Solve R*X = Y;
            for (int k = n - 1; k >= 0; k--)
            {
                for (int j = 0; j < nx; j++)
                {
                    X.data[k][j] /= r_.data[k][k];
                }
                for (int i = 0; i < k; i++)
                {
                    for (int j = 0; j < nx; j++)
                    {
                        X.data[i][j] -= X.data[k][j] * r_.data[i][k];
                    }
                }
            }
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < nx; j++)
                {
                    ret.data[i][j] = X.data[i][j];
                }
            }
#else
            Complex[] c = new Complex[B.data.Length];
            Array.Copy(B.data, 0, c, 0, B.data.Length);
            Lapack.Unmqr.Compute(Lapack.Side.Left, Lapack.Transpose.ConjTrans, m, nx, n, qr, m, tau, c, m);
            Blas.Trsm.Compute(Blas.Order.ColumnMajor, Blas.Side.Left, Blas.UpLo.Upper, Blas.Transpose.NoTrans, Blas.Diag.NonUnit,
                              n, nx, 1, qr, m, c, m);

            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < nx; j++)
                {
                    ret.data[j * n + i] = c[j * m + (jpvt[i] - 1)];
                }
            }
#endif
            return(ret);
        }
示例#19
0
        internal static void Compute(Order order, Transpose transA, int m, int n, Complex alpha, Complex[] A, int lda, Complex[] X, int incx, Complex beta, Complex[] Y, int incy)
        {
            ArgumentCheck(order, transA, m, n, A, A.Length, lda, X, X.Length, ref incx, Y, Y.Length, ref incy);

#if MANAGED
            int lenX = m;
            int lenY = n;

            if (transA == Transpose.NoTrans)
            {
                lenX = n;
                lenY = m;
            }
            if (beta == Complex.Zero)
            {
                for (int i = 0, iy = 0; i < lenY; ++i, iy += incy)
                {
                    Y[iy] = 0;
                }
            }
            else if (beta != Complex.One)
            {
                for (int i = 0, iy = 0; i < lenY; ++i, iy += incy)
                {
                    Y[iy] *= beta;
                }
            }
            if (alpha == Complex.Zero)
            {
                return;
            }
            Complex add_val = new Complex(0);
            if ((order == Order.RowMajor && transA == Transpose.NoTrans) ||
                (order == Order.ColumnMajor && transA == Transpose.Trans))
            {
                for (int i = 0, iy = 0; i < lenY; ++i, iy += incy)
                {
                    add_val = 0;
                    for (int j = 0, jx = 0; j < lenX; ++j, jx += incx)
                    {
                        add_val += X[jx] * A[i * lda + j];
                    }
                    Y[iy] += alpha * add_val;
                }
            }
            else if ((order == Order.RowMajor && transA == Transpose.Trans) ||
                     (order == Order.ColumnMajor && transA == Transpose.NoTrans))
            {
                for (int j = 0, jx = 0; j < lenX; ++j, jx += incx)
                {
                    add_val = alpha * X[jx];
                    if (add_val != Complex.Zero)
                    {
                        for (int i = 0, iy = 0; i < lenY; ++i, iy += incy)
                        {
                            Y[iy] += add_val * A[j * lda + i];
                        }
                    }
                }
            }
            else if (order == Order.RowMajor && transA == Transpose.ConjTrans)
            {
                for (int j = 0, jx = 0; j < lenX; ++j, jx += incx)
                {
                    add_val = alpha * X[jx];
                    if (add_val != Complex.Zero)
                    {
                        for (int i = 0, iy = 0; i < lenY; ++i, iy += incy)
                        {
                            Y[iy] += add_val * ComplexMath.Conjugate(A[j * lda + i]);
                        }
                    }
                }
            }
            else
            {
                for (int i = 0, iy = 0; i < lenY; ++i, iy += incy)
                {
                    add_val = 0;
                    for (int j = 0, jx = 0; j < lenX; ++j, jx += incx)
                    {
                        add_val += X[jx] * ComplexMath.Conjugate(A[i * lda + j]);
                    }
                    Y[iy] += alpha * add_val;
                }
            }
#else
            dna_blas_zgemv(order, transA, m, n, ref alpha, A, lda, X, incx, ref beta, Y, incy);
#endif
        }
        ///<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 ComplexDoubleVector(mm); // singular values
#if MANAGED
            // Derived from LINPACK code.
            // Initialize.
            u = new ComplexDoubleMatrix(rows, rows); // left vectors
            v = new ComplexDoubleMatrix(cols, cols); // right vectors
            ComplexDoubleVector e    = new ComplexDoubleVector(cols);
            ComplexDoubleVector work = new ComplexDoubleVector(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;
            Complex 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 = dznrm2Column(matrix, l, l);
                    s[l]  = new Complex(xnorm, (double)0.0);
                    if (dcabs1(s[l]) != 0.0)
                    {
                        if (dcabs1(matrix[l, l]) != 0.0)
                        {
                            s[l] = csign(s[l], matrix[l, l]);
                        }
                        zscalColumn(matrix, l, l, 1.0 / s[l]);
                        matrix[l, l] = Complex.One + matrix[l, l];
                    }

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

                for (j = lp1; j < cols; j++)
                {
                    if (l < nct)
                    {
                        if (dcabs1(s[l]) != 0.0)
                        {
                            // apply the transformation.
                            t = -zdotc(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] = ComplexMath.Conjugate(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 = dznrm2Vector(e, lp1);
                    e[l]  = new Complex(enorm, 0.0);
                    if (dcabs1(e[l]) != 0.0)
                    {
                        if (dcabs1(e[lp1]) != 0.0)
                        {
                            e[l] = csign(e[l], e[lp1]);
                        }
                        zscalVector(e, lp1, 1.0 / e[l]);
                        e[lp1] = Complex.One + e[lp1];
                    }
                    e[l] = ComplexMath.Conjugate(-e[l]);

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

                        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++)
                        {
                            Complex ww = ComplexMath.Conjugate(-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] = Complex.Zero;
            }
            if (nrtp1 < m)
            {
                e[nrtp1 - 1] = matrix[nrtp1 - 1, m - 1];
            }
            e[m - 1] = Complex.Zero;

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

                for (l = nct - 1; l >= 0; l--)
                {
                    if (dcabs1(s[l]) != 0.0)
                    {
                        for (j = l + 1; j < ncu; j++)
                        {
                            t = -zdotc(u, l, j, l) / u[l, l];
                            for (int ii = l; ii < u.RowLength; ii++)
                            {
                                u[ii, j] += t * u[ii, l];
                            }
                        }
                        zscalColumn(u, l, l, -Complex.One);
                        u[l, l] = Complex.One + u[l, l];
                        for (i = 0; i < l; i++)
                        {
                            u[i, l] = Complex.Zero;
                        }
                    }
                    else
                    {
                        for (i = 0; i < rows; i++)
                        {
                            u[i, l] = Complex.Zero;
                        }
                        u[l, l] = Complex.One;
                    }
                }
            }

            //   if it is required, generate v.
            if (computeVectors)
            {
                for (l = cols - 1; l >= 0; l--)
                {
                    lp1 = l + 1;
                    if (l < nrt)
                    {
                        if (dcabs1(e[l]) != 0.0)
                        {
                            for (j = lp1; j < cols; j++)
                            {
                                t = -zdotc(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] = Complex.Zero;
                    }
                    v[l, l] = Complex.One;
                }
            }

            //   transform s and e so that they are  double .
            for (i = 0; i < m; i++)
            {
                if (dcabs1(s[i]) != 0.0)
                {
                    t    = new Complex(ComplexMath.Absolute(s[i]), 0.0);
                    r    = s[i] / t;
                    s[i] = t;
                    if (i < m - 1)
                    {
                        e[i] = e[i] / r;
                    }
                    if (computeVectors)
                    {
                        zscalColumn(u, i, 0, r);
                    }
                }
                //   ...exit
                if (i == m - 1)
                {
                    break;
                }
                if (dcabs1(e[i]) != 0.0)
                {
                    t        = new Complex(ComplexMath.Absolute(e[i]), 0.0);
                    r        = t / e[i];
                    e[i]     = t;
                    s[i + 1] = s[i + 1] * r;
                    if (computeVectors)
                    {
                        zscalColumn(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] = Complex.Zero;
                        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] = Complex.Zero;
                            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].Real;
                    e[m - 2] = Complex.Zero;
                    for (k = m - 2; k >= 0; k--)
                    {
                        t1 = s[k].Real;
                        drotg(ref t1, ref f, ref cs, ref sn);
                        s[k] = new Complex(t1, 0.0);
                        if (k != l)
                        {
                            f        = -sn * e[k - 1].Real;
                            e[k - 1] = cs * e[k - 1];
                        }
                        if (computeVectors)
                        {
                            zdrot(v, k, m - 1, cs, sn);
                        }
                    }
                    break;

                // split at negligible s[l].
                case 2:
                    f        = e[l - 1].Real;
                    e[l - 1] = Complex.Zero;
                    for (k = l; k < m; k++)
                    {
                        t1 = s[k].Real;
                        drotg(ref t1, ref f, ref cs, ref sn);
                        s[k] = new Complex(t1, 0.0);
                        f    = -sn * e[k].Real;
                        e[k] = cs * e[k];
                        if (computeVectors)
                        {
                            zdrot(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].Real / scale;
                    smm1  = s[m - 2].Real / scale;
                    emm1  = e[m - 2].Real / scale;
                    sl    = s[l].Real / scale;
                    el    = e[l].Real / 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] = new Complex(f, 0.0);
                        }
                        f        = cs * s[k].Real + sn * e[k].Real;
                        e[k]     = cs * e[k] - sn * s[k];
                        g        = sn * s[k + 1].Real;
                        s[k + 1] = cs * s[k + 1];
                        if (computeVectors)
                        {
                            zdrot(v, k, k + 1, cs, sn);
                        }
                        drotg(ref f, ref g, ref cs, ref sn);
                        s[k]     = new Complex(f, 0.0);
                        f        = cs * e[k].Real + sn * s[k + 1].Real;
                        s[k + 1] = -sn * e[k] + cs * s[k + 1];
                        g        = sn * e[k + 1].Real;
                        e[k + 1] = cs * e[k + 1];
                        if (computeVectors && k < rows)
                        {
                            zdrot(u, k, k + 1, cs, sn);
                        }
                    }
                    e[m - 2] = new  Complex(f, 0.0);
                    iter     = iter + 1;
                    break;

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

                    // order the singular value.
                    while (l != mm - 1)
                    {
                        if (s[l].Real >= s[l + 1].Real)
                        {
                            break;
                        }
                        t        = s[l];
                        s[l]     = s[l + 1];
                        s[l + 1] = t;
                        if (computeVectors && l < cols)
                        {
                            zswap(v, l, l + 1);
                        }
                        if (computeVectors && l < rows)
                        {
                            zswap(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
            double[] d = new double[mm];
            u = new ComplexDoubleMatrix(rows);
            v = new ComplexDoubleMatrix(cols);
            Complex[] a = new Complex[matrix.data.Length];
            Array.Copy(matrix.data, a, matrix.data.Length);
            Lapack.Gesvd.Compute(rows, cols, a, d, u.data, v.data);
            v.ConjugateTranspose();
            for (int i = 0; i < d.Length; i++)
            {
                s[i] = d[i];
            }
#endif
            w = new ComplexDoubleMatrix(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].Real * eps;
            rank = 0;

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

            if (!computeVectors)
            {
                u = null;
                v = null;
            }
            matrix = null;
        }