示例#1
0
文件: MatrixQ.cs 项目: Swipes13/smad
        /// <summary>
        /// Generates diagonal matrix
        /// </summary>
        /// <param name="diag_vector">column vector containing the diag elements</param>
        /// <returns></returns>
        public static MatrixQ Diag(MatrixQ 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.");

              MatrixQ M = new MatrixQ(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;
        }
示例#2
0
文件: MatrixQ.cs 项目: Swipes13/smad
        /// <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(MatrixQ v, MatrixQ 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;
        }
示例#3
0
文件: MatrixQ.cs 项目: Swipes13/smad
        /// <summary>
        /// Computes the Householder vector.
        /// </summary>
        /// <param name="x"></param>
        /// <returns></returns>
        private static MatrixQ[] HouseholderVector(MatrixQ 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.");

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

              MatrixQ 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 MatrixQ[] { v, new MatrixQ(beta) };
        }
示例#4
0
文件: MatrixQ.cs 项目: Swipes13/smad
        /// <summary>
        /// Generates diagonal matrix
        /// </summary>
        /// <param name="diag_vector">column vector containing the diag elements</param>
        /// <returns></returns>
        public static MatrixQ Diag(MatrixQ diag_vector)
        {
            int dim = diag_vector.VectorLength();

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

              MatrixQ M = new MatrixQ(dim, dim);

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

              return M;
        }
示例#5
0
文件: MatrixQ.cs 项目: Swipes13/smad
        /// <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(MatrixQ 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);
              }
        }
示例#6
0
文件: MatrixQ.cs 项目: Swipes13/smad
        /// <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(MatrixQ 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);
              }
        }
示例#7
0
文件: MatrixQ.cs 项目: Swipes13/smad
        /// <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(MatrixQ 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];
        }
示例#8
0
文件: MatrixQ.cs 项目: Swipes13/smad
        /// <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(MatrixQ 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];
        }
示例#9
0
文件: MatrixQ.cs 项目: Swipes13/smad
        /// <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 MatrixQ TriDiag(MatrixQ l, MatrixQ d, MatrixQ 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);
        }