Example #1
0
        /// <summary>
        /// Generates tri-diagonal square matrix with overloaded vectors
        /// as main and secondary diagonals. The dimension of the output
        /// matrix is determined by the length of d.
        /// </summary>
        /// <param name="l">Lower secondary diagonal vector.</param>
        /// <param name="d">Main diagonal vector.</param>
        /// <param name="u">Upper secondary diagonal vector.</param>
        /// <returns></returns>
        public static Matrix TriDiag(Matrix l, Matrix d, Matrix u)
        {
            int sizeL = l.VectorLength();
            int sizeD = d.VectorLength();
            int sizeU = u.VectorLength();

            if (sizeL * sizeD * sizeU == 0)
                throw new ArgumentException("At least one of the paramter matrices is not a vector.");

            if (sizeL != sizeU)
                throw new ArgumentException("Lower and upper secondary diagonal must have the same length.");

            if (sizeL + 1 != sizeD)
                throw new ArgumentException("Main diagonal must have exactly one element more than the secondary diagonals.");

            return Diag(l, -1) + Diag(d) + Diag(u, 1);
        }
Example #2
0
        /// <summary>
        /// Implements the dot product of two vectors.
        /// </summary>
        /// <param name="v">Row or column vector.</param>
        /// <param name="w">Row or column vector.</param>
        /// <returns>Dot product.</returns>
        public static Complex Dot(Matrix v, Matrix w)
        {
            int m = v.VectorLength();
            int n = w.VectorLength();

            if (m == 0 || n == 0)
                throw new ArgumentException("Arguments need to be vectors.");
            else if (m != n)
                throw new ArgumentException("Vectors must be of the same length.");

            Complex buf = Complex.Zero;

            for (int i = 1; i <= m; i++)
            {
                buf += v[i] * w[i];
            }

            return buf;
        }
Example #3
0
        /// <summary>
        /// Generates diagonal matrix
        /// </summary>
        /// <param name="diag_vector">column vector containing the diag elements</param>
        /// <returns></returns>
        public static Matrix Diag(Matrix diag_vector)
        {
            int dim = diag_vector.VectorLength();
            
            if(dim == 0)
                throw new ArgumentException("diag_vector must be 1xN or Nx1");

            Matrix M = new Matrix(dim, dim);

            for (int i = 1; i <= dim; i++)
            {
                M[i, i] = diag_vector[i];
            }

            return M;

        }
Example #4
0
        /// <summary>
        /// Generates diagonal matrix
        /// </summary>
        /// <param name="diag_vector">column vector containing the diag elements</param>
        /// <returns></returns>
        public static Matrix Diag(Matrix diag_vector, int offset)
        {
            int dim = diag_vector.VectorLength();
            

            if(dim == 0)
                throw new ArgumentException("diag_vector must be 1xN or Nx1.");

            //if (Math.Abs(offset) >= dim)
            //    throw new ArgumentException("Absolute value of offset must be less than length of diag_vector.");

            Matrix M = new Matrix(dim + Math.Abs(offset), dim + Math.Abs(offset));
            dim = M.RowCount;

            if (offset >= 0)
            {
                for (int i = 1; i <= dim - offset; i++)
                {
                    M[i, i + offset] = diag_vector[i];
                }
            }
            else
            {
                for (int i = 1; i <= dim + offset; i++)
                {
                    M[i - offset, i] = diag_vector[i];
                }
            }

            return M;

        }
Example #5
0
        /// <summary>
        /// Performs backward insertion for regular upper triangular matrix
        /// and right side b, such that the solution is saved right within b.
        /// The matrix is not changed.
        /// </summary>
        /// <param name="b">Vector of height n, if matrix is n by n.</param>
        public void BackwardInsertion(Matrix b)
        {
            if (!this.IsUpperTriangular())
                throw new InvalidOperationException("Cannot perform backward insertion for matrix not being upper triangular.");

            if (/*this.Determinant*/this.DiagProd() == 0)
                throw new InvalidOperationException("Warning: Matrix is nearly singular.");

            int n = rowCount;

            if (b.VectorLength() != n)
                throw new ArgumentException("Parameter must vector of the same height as matrix.");

            for (int j = n; j >= 2; j--)
            {
                b[j] /= this[j, j];

                for (int i = 1; i <= j - 1; i++)
                    b[i] -= b[j] * this[i, j];
            }

            b[1] /= this[1, 1];
        }
Example #6
0
        /// <summary>
        /// Performs forward insertion for regular lower triangular matrix
        /// and right side b, such that the solution is saved right within b.
        /// The matrix is not changed.
        /// </summary>
        /// <param name="b">Vector of height n, if matrix is n by n.</param>
        public void ForwardInsertion(Matrix b)
        {
            if (!this.IsLowerTriangular())
                throw new InvalidOperationException("Cannot perform forward insertion for matrix not being lower triangular.");

            if (/*this.Determinant*/this.DiagProd() == 0)
                throw new InvalidOperationException("Warning: Matrix is nearly singular.");

            int n = rowCount;

            if (b.VectorLength() != n)
                throw new ArgumentException("Parameter must vector of the same height as matrix.");

            for (int j = 1; j <= n - 1; j++)
            {
                b[j] /= this[j, j];

                for (int i = 1; i <= n - j; i++)
                    b[j + i] -= b[j] * this[j + i, j];
            }

            b[n] /= this[n, n];
        }
Example #7
0
        /// <summary>
        /// Inserts column at specified index.
        /// </summary>
        /// <param name="col">Vector to insert</param>
        /// <param name="j">One-based index at which to insert</param>
        public void InsertColumn(Matrix col, int j)
        {
            int size = col.VectorLength();

            if (size == 0)
                throw new InvalidOperationException("Row must be a vector of length > 0.");

            if (j <= 0)
                throw new ArgumentException("Row index must be positive.");


            if (j > columnCount)
            {
                this[size, j] = Complex.Zero;
            }
            else
                columnCount++;

            if (size > rowCount)
            {
                this[size, j] = Complex.Zero;
            }

            j--;

            for (int k = 0; k < size; k++)
            {
                ((ArrayList)Values[k]).Insert(j, col[k + 1]);
            }

            // fill w/ zeros if vector col too short
            for (int k = size; k < rowCount; k++)
            {
                ((ArrayList)Values[k]).Insert(j, 0);
            }

        }
Example #8
0
        /// <summary>
        /// Inserts row at specified index.
        /// </summary>
        /// <param name="row">Vector to insert</param>
        /// <param name="i">One-based index at which to insert</param>
        public void InsertRow(Matrix row, int i)
        {
            int size = row.VectorLength();

            if (size == 0)
                throw new InvalidOperationException("Row must be a vector of length > 0.");

            if (i <= 0)
                throw new ArgumentException("Row index must be positive.");


            if (i > rowCount)
                this[i, size] = Complex.Zero;

            else if (size > columnCount)
            {
                this[i, size] = Complex.Zero;
                rowCount++;
            }
            else
                rowCount++;



            Values.Insert(--i, new ArrayList(size));
            //Debug.WriteLine(Values.Count.ToString());

            for (int k = 1; k <= size; k++)
            {
                ((ArrayList)Values[i]).Add(row[k]);
            }

            // fill w/ zeros if vector row is too short
            for (int k = size; k < columnCount; k++)
            {
                ((ArrayList)Values[i]).Add(Complex.Zero);
            }
        }
Example #9
0
        /// <summary>
        /// Computes the Householder vector.
        /// </summary>
        /// <param name="x"></param>
        /// <returns></returns>
        private static Matrix[] HouseholderVector(Matrix x)
        {
            //throw new NotImplementedException("Supposingly buggy!");

            //if (!x.IsReal())
            //    throw new ArgumentException("Cannot compute housholder vector of non-real vector.");

            int n = x.VectorLength();

            if (n == 0)
                throw new InvalidOperationException("Expected vector as argument.");

            Matrix y = x / x.Norm();
            Matrix buf = y.Extract(2, n, 1, 1);
            Complex s = Dot(buf, buf);

            Matrix v = Zeros(n, 1);
            v[1] = Complex.One;

            v.Insert(2, 1, buf);

            double beta = 0;

            if (s != 0)
            {
                Complex mu = Complex.Sqrt(y[1] * y[1] + s);
                if (y[1].Re <= 0)
                    v[1] = y[1] - mu;
                else
                    v[1] = -s / (y[1] + mu);

                beta = 2 * v[1].Re * v[1].Re / (s.Re + v[1].Re * v[1].Re);
                v = v / v[1];
            }

            return new Matrix[] { v, new Matrix(beta) };
            
        }