/// <summary>
        /// Matrix ^ scalar
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public QsMatrix PowerScalar(QsScalar value)
        {
            QsMatrix Total = (QsMatrix)this.Identity; //first get the identity matrix of this matrix.

            int count = Qs.IntegerFromQsValue(value);

            if (count > 0)
            {
                for (int i = 1; i <= count; i++)
                {
                    Total = Total.MultiplyMatrix(this);
                }
            }
            else if (count == 0)
            {
                return(Total);   //which id identity already
            }
            else
            {
                count = Math.Abs(count);
                for (int i = 1; i <= count; i++)
                {
                    Total = Total.MultiplyMatrix(this.Inverse);    //multiply the inverses many times
                }
            }

            return(Total);
        }
예제 #2
0
        /// <summary>
        /// Matrix - Matrix
        /// </summary>
        /// <param name="matrix"></param>
        /// <returns></returns>
        private QsMatrix SubtractMatrix(QsMatrix matrix)
        {
            if (this.DimensionEquals(matrix))
            {
                QsMatrix Total = new QsMatrix();
                for (int IY = 0; IY < this.RowsCount; IY++)
                {
                    List <QsScalar> row = new List <QsScalar>(ColumnsCount);

                    for (int IX = 0; IX < this.ColumnsCount; IX++)
                    {
                        row.Add(this[IY, IX] - matrix[IY, IX]);
                    }

                    Total.AddRow(row.ToArray());
                }
                return(Total);
            }
            else
            {
                throw new QsMatrixException("Matrix 1 [" + this.RowsCount.ToString(CultureInfo.InvariantCulture)
                                            + "x" + this.ColumnsCount.ToString(CultureInfo.InvariantCulture) +
                                            "] is not dimensional equal with Matrix 2 [" + matrix.RowsCount.ToString(CultureInfo.InvariantCulture)
                                            + "x" + matrix.ColumnsCount.ToString(CultureInfo.InvariantCulture) + "]");
            }
        }
예제 #3
0
        /// <summary>
        /// Normal multiplication.
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public override QsValue MultiplyOperation(QsValue vl)
        {
            QsValue value;

            if (vl is QsReference)
            {
                value = ((QsReference)vl).ContentValue;
            }
            else
            {
                value = vl;
            }


            if (value is QsScalar)
            {
                return(MultiplyScalar((QsScalar)value));
            }
            else if (value is QsVector)
            {
                return(this.MultiplyVector((QsVector)value));
            }
            else if (value is QsMatrix)
            {
                QsMatrix mvec = this.ToVectorMatrix().MultiplyMatrix((QsMatrix)value);
                // make it vector again.
                return(mvec[0]);
            }
            else
            {
                throw new NotSupportedException();
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public override QsValue DifferentiateOperation(QsValue vl)
        {
            QsValue value;

            if (vl is QsReference)
            {
                value = ((QsReference)vl).ContentValue;
            }
            else
            {
                value = vl;
            }


            if (value is QsScalar)
            {
                QsMatrix n = new QsMatrix();
                foreach (var row in n.Rows)
                {
                    n.AddRow(row.DifferentiateScalar((QsScalar)value).ToArray());
                }
                return(n);
            }
            else
            {
                return(base.DifferentiateOperation(value));
            }
        }
예제 #5
0
        /// <summary>
        /// Gets a specific covector as a matrix object.
        /// </summary>
        /// <param name="columnIndex"></param>
        /// <returns></returns>
        public QsMatrix GetColumnVectorMatrix(int columnIndex)
        {
            QsMatrix mat = new QsMatrix();

            mat.AddColumnVector(GetColumnVector(columnIndex));
            return(mat);
        }
예제 #6
0
        public QsMatrix AppendLowerMatrix(QsMatrix matrix)
        {
            QsMatrix m = CopyMatrix(this);

            foreach (var vector in matrix)
            {
                m.AddVector(vector);
            }
            return(m);
        }
예제 #7
0
        /// <summary>
        /// Append the target matrix right to the matrix.
        /// </summary>
        /// <param name="matrix"></param>
        /// <returns></returns>
        public QsMatrix AppendRightMatrix(QsMatrix matrix)
        {
            QsMatrix m = CopyMatrix(this);

            foreach (var column in matrix.Columns)
            {
                m.AddColumnVector(column);
            }
            return(m);
        }
예제 #8
0
        /// <summary>
        /// Copy the matrix into new matrix instance.
        /// </summary>
        /// <param name="matrix"></param>
        /// <returns></returns>
        public static QsMatrix CopyMatrix(QsMatrix matrix)
        {
            QsMatrix m = new QsMatrix();

            foreach (QsVector v in matrix)
            {
                m.AddVector(QsVector.CopyVector(v));
            }

            return(m);
        }
        /// <summary>
        /// for the tensor product '(*)'  operator
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public override QsValue TensorProductOperation(QsValue vl)
        {
            QsValue value;

            if (vl is QsReference)
            {
                value = ((QsReference)vl).ContentValue;
            }
            else
            {
                value = vl;
            }


            if (value is QsMatrix)
            {
                // Kronecker product
                var tm = (QsMatrix)value;

                QsMatrix result = new QsMatrix();

                List <QsMatrix> lm = new List <QsMatrix>();

                for (int i = 0; i < this.RowsCount; i++)
                {
                    QsMatrix rowM = null;
                    for (int j = 0; j < this.ColumnsCount; j++)
                    {
                        QsScalar element = this[i, j];
                        var      imat    = (QsMatrix)(tm * element);
                        if (rowM == null)
                        {
                            rowM = imat;
                        }
                        else
                        {
                            rowM = rowM.AppendRightMatrix(imat);
                        }
                    }
                    lm.Add(rowM);
                }

                // append vertically all matrices

                foreach (var rm in lm)
                {
                    result = result.AppendLowerMatrix(rm);
                }

                return(result);
            }
            throw new NotImplementedException();
        }
예제 #10
0
        /// <summary>
        /// Transfer the columns of the matrix into rows.
        /// </summary>
        /// <returns></returns>
        public QsMatrix Transpose()
        {
            QsMatrix m = new QsMatrix();

            for (int IX = 0; IX < ColumnsCount; IX++)
            {
                var vec = this.GetColumnVectorMatrix(IX);

                m.AddRow(vec.ToArray());
            }
            return(m);
        }
        /// <summary>
        /// Removes row at index
        /// </summary>
        /// <param name="rowIndex"></param>
        /// <returns></returns>
        public QsMatrix RemoveRow(int rowIndex)
        {
            QsMatrix m = new QsMatrix();

            for (int iy = 0; iy < this.RowsCount; iy++)
            {
                if (iy != rowIndex)
                {
                    m.AddVector(this[iy]);
                }
            }
            return(m);
        }
        /// <summary>
        /// Removes column at index
        /// </summary>
        /// <param name="columnIndex"></param>
        /// <returns></returns>
        public QsMatrix RemoveColumn(int columnIndex)
        {
            QsMatrix m = new QsMatrix();

            for (int ix = 0; ix < this.ColumnsCount; ix++)
            {
                if (ix != columnIndex)
                {
                    m.AddColumnVector(this.GetColumnVector(ix));
                }
            }
            return(m);
        }
예제 #13
0
        public QsMatrix GetVectorMatrix(int rowIndex)
        {
            if (rowIndex > RowsCount)
            {
                throw new QsMatrixException("Index '" + rowIndex + "' Exceeds the rows limits '" + RowsCount + "'");
            }

            QsMatrix mat = new QsMatrix();

            mat.AddVector(QsVector.CopyVector(Rows[rowIndex]));

            return(mat);
        }
예제 #14
0
        /// <summary>
        /// Makes n x n matrix with zeros.
        /// </summary>
        /// <param name="n"></param>
        /// <returns></returns>
        public static QsMatrix MakeEmptySquareMatrix(int n)
        {
            QsMatrix m = new QsMatrix();

            for (int i = 0; i < n; i++)
            {
                QsVector v = new QsVector(n);
                for (int j = 0; j < n; j++)
                {
                    v.AddComponent(QsScalar.Zero);
                }
                m.AddVector(v);
            }
            return(m);
        }
예제 #15
0
        /// <summary>
        /// The function receive rows from vectors or matrices or may be tensors
        /// </summary>
        /// <param name="values">Vectors</param>
        /// <returns></returns>
        public static QsValue MatrixFromValues(params QsValue[] values)
        {
            if (values[0] is QsTensor)
            {
                if (values.Count() == 1)
                {
                    return(values[0]);
                }

                // treat the case of tensors
                QsTensor tensor = new QsTensor();
                foreach (var tn in values)
                {
                    if (tn.GetType() != typeof(QsTensor))
                    {
                        throw new QsException("Non Tensor in a matrix of tensors is not valid expression.");
                    }
                    else
                    {
                        tensor.AddInnerTensor((QsTensor)tn);
                    }
                }
                return(tensor);
            }

            QsMatrix mat = new QsMatrix();

            foreach (var val in values)
            {
                if (val is QsVector)
                {
                    mat.AddVector((QsVector)val);
                }
                else if (val is QsMatrix)
                {
                    foreach (var vc in ((QsMatrix)val))
                    {
                        mat.AddVector((QsVector)vc);
                    }
                }
                else
                {
                    throw new QsInvalidOperationException("Value to be added is not a vector nor a matrix.");
                }
            }

            return(mat);
        }
        /// <summary>
        /// Matrix elements ^. scalar
        /// </summary>
        /// <param name="scalarQuantity"></param>
        /// <returns></returns>
        public QsMatrix ElementsPowerScalar(QsScalar scalar)
        {
            QsMatrix Total = new QsMatrix();

            for (int IY = 0; IY < this.RowsCount; IY++)
            {
                List <QsScalar> row = new List <QsScalar>(ColumnsCount);

                for (int IX = 0; IX < this.ColumnsCount; IX++)
                {
                    row.Add(this[IY, IX].PowerScalar(scalar));
                }

                Total.AddRow(row.ToArray());
            }
            return(Total);
        }
        /// <summary>
        /// Matrix + scalar
        /// </summary>
        /// <param name="scalar"></param>
        /// <returns></returns>
        private QsMatrix AddScalar(QsScalar scalar)
        {
            QsMatrix Total = new QsMatrix();

            for (int IY = 0; IY < this.RowsCount; IY++)
            {
                List <QsScalar> row = new List <QsScalar>(ColumnsCount);

                for (int IX = 0; IX < this.ColumnsCount; IX++)
                {
                    row.Add(this[IY, IX] + scalar);
                }

                Total.AddRow(row.ToArray());
            }
            return(Total);
        }
예제 #18
0
        /// <summary>
        /// Ordinary multiplicatinon of the matrix.
        /// Naive implementation :D  and I am proud :P
        ///
        /// </summary>
        /// <param name="matrix"></param>
        /// <returns></returns>
        public QsMatrix MultiplyMatrix(QsMatrix matrix)
        {
            if (this.ColumnsCount == matrix.RowsCount)
            {
                QsMatrix Total = new QsMatrix();

                //loop through my rows
                for (int iy = 0; iy < RowsCount; iy++)
                {
                    var        vec  = this.Rows[iy];
                    QsScalar[] tvec = new QsScalar[matrix.ColumnsCount]; //the target row in the Total Matrix.

                    //loop through all co vectors in the target matrix.
                    for (int tix = 0; tix < matrix.ColumnsCount; tix++)
                    {
                        var covec = matrix.GetColumnVectorMatrix(tix).ToArray();

                        //multiply vec*covec and store it at the Total matrix at iy,ix

                        QsScalar[] snum = new QsScalar[vec.Count];
                        for (int i = 0; i < vec.Count; i++)
                        {
                            snum[i] = vec[i].MultiplyScalar(covec[i]);
                        }

                        QsScalar tnum = snum[0];

                        for (int i = 1; i < snum.Length; i++)
                        {
                            tnum = tnum + snum[i];
                        }

                        tvec[tix] = tnum;
                    }

                    Total.AddRow(tvec);
                }

                return(Total);
            }
            else
            {
                throw new QsMatrixException("Width of the first matrix [" + this.ColumnsCount + "] not equal to the height of the second matrix [" + matrix.RowsCount + "]");
            }
        }
예제 #19
0
 /// <summary>
 /// used to make sure that the two matrices are dimensionally equal
 /// have the same count of rows and columnss
 /// </summary>
 /// <param name="obj"></param>
 /// <returns></returns>
 public bool DimensionEquals(QsMatrix matrix)
 {
     if (matrix == null)
     {
         return(false);
     }
     else
     {
         if (this.RowsCount == matrix.RowsCount)
         {
             if (this.ColumnsCount == matrix.ColumnsCount)
             {
                 return(true);   //just for now.
             }
         }
         //dimensions not equal.
         return(false);
     }
 }
        /// <summary>
        /// '>>' Right Shift Operator
        /// </summary>
        /// <param name="times"></param>
        /// <returns></returns>
        public override QsValue RightShiftOperation(QsValue vl)
        {
            QsValue times;

            if (vl is QsReference)
            {
                times = ((QsReference)vl).ContentValue;
            }
            else
            {
                times = vl;
            }


            QsMatrix ShiftedMatrix = new QsMatrix();

            foreach (var vec in this)
            {
                ShiftedMatrix.AddVector((QsVector)vec.RightShiftOperation(times));
            }
            return(ShiftedMatrix);
        }
예제 #21
0
        /// <summary>
        /// Cross product for 3 components vector.
        /// </summary>
        /// <param name="v1"></param>
        /// <param name="v2"></param>
        /// <returns></returns>
        public QsVector VectorProduct(QsVector v2)
        {
            if (this.Count != v2.Count)
            {
                throw new QsException("Vectors are not equal");
            }
            if (this.Count != 3)
            {
                throw new QsException("Cross product only happens with 3 component vector");
            }

            // cross product as determinant of matrix.

            QsMatrix mat = new QsMatrix(
                new QsVector(QsScalar.One, QsScalar.One, QsScalar.One)
                , this
                , v2);

            return(mat.Determinant());

            // problem now: what if we have more than 3 elements in the vector.
            // there is no cross product for more than 3 elements for vectors.
        }
예제 #22
0
        /// <summary>
        /// Make identity matrix bases on dimension
        /// </summary>
        /// <param name="n">dimension or n * n matrix</param>
        /// <returns></returns>
        public static QsMatrix MakeIdentity(int n)
        {
            QsMatrix m = new QsMatrix();

            for (int i = 0; i < n; i++)
            {
                QsVector v = new QsVector(n);
                for (int j = 0; j < n; j++)
                {
                    if (j == i)
                    {
                        v.AddComponent(QsScalar.One);
                    }
                    else
                    {
                        v.AddComponent(QsScalar.Zero);
                    }
                }
                m.AddVector(v);
            }

            return(m);
        }
        public override QsValue Execute(Token expression)
        {
            string operation = expression.TokenValue;

            if (operation.Equals("Transpose()", StringComparison.OrdinalIgnoreCase))
            {
                return(this.Transpose());
            }

            if (operation.Equals("Identity", StringComparison.OrdinalIgnoreCase))
            {
                return(this.Identity);
            }

            if (operation.Equals("Determinant", StringComparison.OrdinalIgnoreCase))
            {
                return(QsMatrix.Determinant(this));
            }

            if (operation.Equals("Cofactors", StringComparison.OrdinalIgnoreCase))
            {
                return(this.Cofactors);
            }

            if (operation.Equals("Adjoint", StringComparison.OrdinalIgnoreCase))
            {
                return(this.Adjoint);
            }

            if (operation.Equals("Inverse", StringComparison.OrdinalIgnoreCase))
            {
                return(this.Inverse);
            }


            throw new QsException("Not implemented or Unknow method for the matrix type");
        }
예제 #24
0
        /// <summary>
        /// Create A matrix from a row values by aligning values to the left in
        /// </summary>
        /// <param name="values"></param>
        /// <returns></returns>
        public static QsValue MatrixRowFromValues(params QsValue[] values)
        {
            // what about [g g] and g is tensor
            // in this case return value should be tensor
            //   from the higher degree of above g
            if (values[0] is QsTensor)
            {
                if (values.Count() == 1)
                {
                    return(values[0]);
                }

                // in rare cases or event known cases by me Ahmed Sadek and because of parsing
                // sometimes I enclose tensor variable inside matrix  [g g <|4 3|> ]
                // so in this case i will the return as it is.

                QsTensor tensor = new QsTensor();
                foreach (var inTensor in values)
                {
                    if (inTensor.GetType() != typeof(QsTensor))
                    {
                        throw new QsException("Non Tensor in a matrix of tensors is not valid expression.");
                    }
                    else
                    {
                        tensor.AddInnerTensor((QsTensor)inTensor);
                    }
                }
                return(tensor);
            }



            QsMatrix m = new QsMatrix();

            foreach (var v in values)
            {
                if (v is QsScalar)
                {
                    if (m.RowsCount == 0)
                    {
                        m.AddVector((QsVector)VectorFromValues(v));
                    }
                    else
                    {
                        m.Rows[0].AddComponent((QsScalar)v);
                    }
                }

                if (v is QsVector)
                {
                    if (m.RowsCount == 0)
                    {
                        m.AddVector(((QsVector)v).Clone() as QsVector);
                    }
                    else if (m.RowsCount == 1)
                    {
                        m.Rows[0].AddComponents((QsVector)v);
                    }
                    else
                    {
                        throw new QsInvalidOperationException("Couldn't adding vector to multi row matrix");
                    }
                }

                if (v is QsMatrix)
                {
                    if (m.RowsCount == 0)
                    {
                        m = null;
                        m = QsMatrix.CopyMatrix((QsMatrix)v);
                    }
                    else if (m.RowsCount == ((QsMatrix)v).RowsCount)
                    {
                        foreach (var col in ((QsMatrix)v).Columns)
                        {
                            m.AddColumnVector(col);
                        }
                    }
                    else
                    {
                        throw new QsInvalidOperationException("Couldn't adding different row matrices");
                    }
                }
            }

            return(m);
        }
예제 #25
0
        // Contribution by Edward Popko, a well commented version: determinant.c for Microsoft C++ Visual Studio 6.
        // http://local.wasp.uwa.edu.au/~pbourke/miscellaneous/determinant/determinant.c
        //==============================================================================
        // Recursive definition of determinate using expansion by minors.
        //
        // Notes: 1) arguments:
        //             a (double **) pointer to a pointer of an arbitrary square matrix
        //             n (int) dimension of the square matrix
        //
        //        2) Determinant is a recursive function, calling itself repeatedly
        //           each time with a sub-matrix of the original till a terminal
        //           2X2 matrix is achieved and a simple determinat can be computed.
        //           As the recursion works backwards, cumulative determinants are
        //           found till untimately, the final determinate is returned to the
        //           initial function caller.
        //
        //        3) m is a matrix (4X4 in example)  and m13 is a minor of it.
        //           A minor of m is a 3X3 in which a row and column of values
        //           had been excluded.   Another minor of the submartix is also
        //           possible etc.
        //             m  a b c d   m13 . . . .
        //                e f g h       e f . h     row 1 column 3 is elminated
        //                i j k l       i j . l     creating a 3 X 3 sub martix
        //                m n o p       m n . p
        //
        //        4) the following function finds the determinant of a matrix
        //           by recursively minor-ing a row and column, each time reducing
        //           the sub-matrix by one row/column.  When a 2X2 matrix is
        //           obtained, the determinat is a simple calculation and the
        //           process of unstacking previous recursive calls begins.
        //
        //                m n
        //                o p  determinant = m*p - n*o
        //
        //        5) this function uses dynamic memory allocation on each call to
        //           build a m X m matrix  this requires **  and * pointer variables
        //           First memory allocation is ** and gets space for a list of other
        //           pointers filled in by the second call to malloc.
        //
        //        6) C++ implements two dimensional arrays as an array of arrays
        //           thus two dynamic malloc's are needed and have corresponsing
        //           free() calles.
        //
        //        7) the final determinant value is the sum of sub determinants
        //
        //==============================================================================

        /*
         * double Determinant(double** a, int n)
         * {
         *  int i, j, j1, j2;                    // general loop and matrix subscripts
         *  double det = 0;                   // init determinant
         *  double** m = NULL;                // pointer to pointers to implement 2d
         *  // square array
         *
         *  if (n < 1) { }                // error condition, should never get here
         *
         *  else if (n == 1)
         *  {                 // should not get here
         *      det = a[0][0];
         *  }
         *
         *  else if (n == 2)
         *  {                // basic 2X2 sub-matrix determinate
         *      // definition. When n==2, this ends the
         *      det = a[0][0] * a[1][1] - a[1][0] * a[0][1];// the recursion series
         *  }
         *
         *
         *                                     // recursion continues, solve next sub-matrix
         *  else
         *  {                             // solve the next minor by building a
         *      // sub matrix
         *      det = 0;                      // initialize determinant of sub-matrix
         *
         *      // for each column in sub-matrix
         *      for (j1 = 0; j1 < n; j1++)
         *      {
         *          // get space for the pointer list
         *          m = (double**)malloc((n - 1) * sizeof(double*));
         *
         *          for (i = 0; i < n - 1; i++)
         *              m[i] = (double*)malloc((n - 1) * sizeof(double));
         *          //     i[0][1][2][3]  first malloc
         *          //  m -> +  +  +  +   space for 4 pointers
         *          //       |  |  |  |          j  second malloc
         *          //       |  |  |  +-> _ _ _ [0] pointers to
         *          //       |  |  +----> _ _ _ [1] and memory for
         *          //       |  +-------> _ a _ [2] 4 doubles
         *          //       +----------> _ _ _ [3]
         *          //
         *          //                   a[1][2]
         *          // build sub-matrix with minor elements excluded
         *          for (i = 1; i < n; i++)
         *          {
         *              j2 = 0;               // start at first sum-matrix column position
         *              // loop to copy source matrix less one column
         *              for (j = 0; j < n; j++)
         *              {
         *                  if (j == j1) continue; // don't copy the minor column element
         *
         *                  m[i - 1][j2] = a[i][j];  // copy source element into new sub-matrix
         *                  // i-1 because new sub-matrix is one row
         *                  // (and column) smaller with excluded minors
         *                  j2++;                  // move to next sub-matrix column position
         *              }
         *          }
         *
         *          det += pow(-1.0, 1.0 + j1 + 1.0) * a[0][j1] * Determinant(m, n - 1);
         *          // sum x raised to y power
         *          // recursively get determinant of next
         *          // sub-matrix which is now one
         *          // row & column smaller
         *
         *          for (i = 0; i < n - 1; i++) free(m[i]);// free the storage allocated to
         *          // to this minor's set of pointers
         *          free(m);                       // free the storage for the original
         *          // pointer to pointer
         *      }
         *  }
         *  return (det);
         * }
         */

        // the code above is converted by  me Ahmed Sadek to support determinant in Qs  :)
        //  I copied the code with the information about who made it to preserve the rights of the person
        //    who made this effort.
        //   Thank you

        public static QsScalar Determinant(QsMatrix a)
        {
            // code taken from: http://local.wasp.uwa.edu.au/~pbourke/miscellaneous/determinant/

            int      n   = a.RowsCount;
            QsScalar det = default(QsScalar);

            if (n < 1)
            {
                throw new QsException("Zero component matrix, are you crazy :)");                       // error condition, should never get here
            }
            else if (n == 1)
            {
                // should not get here
                det = a[0][0];
            }

            else if (n == 2)
            {
                // basic 2X2 sub-matrix determinate
                // definition. When n==2, this ends the
                det = a[0][0] * a[1][1] - a[1][0] * a[0][1];// the recursion series
            }

            // recursion continues, solve next sub-matrix
            else
            {                             // solve the next minor by building a
                // sub matrix

                int i, j, j1, j2;

                QsMatrix m = QsMatrix.MakeEmptySquareMatrix(n - 1);

                // for each column in sub-matrix
                for (j1 = 0; j1 < n; j1++)
                {
                    // build sub-matrix with minor elements excluded
                    for (i = 1; i < n; i++)
                    {
                        j2 = 0;               // start at first sum-matrix column position

                        // loop to copy source matrix less one column
                        for (j = 0; j < n; j++)
                        {
                            if (j == j1)
                            {
                                continue;           // don't copy the minor column element
                            }
                            m[i - 1][j2] = a[i][j]; // copy source element into new sub-matrix
                            // i-1 because new sub-matrix is one row
                            // (and column) smaller with excluded minors
                            j2++;                  // move to next sub-matrix column position
                        }
                    }

                    var fn = System.Math.Pow(-1.0, 1.0 + j1 + 1.0);
                    var f  = fn.ToQuantity().ToScalar();
                    var mr = Determinant(m);

                    if (det == null)
                    {
                        det = f * (a[0][j1] * mr);
                    }
                    else
                    {
                        det += f * (a[0][j1] * mr);
                    }

                    // sum x raised to y power
                    // recursively get determinant of next
                    // sub-matrix which is now one
                    // row & column smaller
                }
            }

            return(det);
        }
예제 #26
0
        public override QsValue MultiplyOperation(QsValue vl)
        {
            QsValue value;

            if (vl is QsReference)
            {
                value = ((QsReference)vl).ContentValue;
            }
            else
            {
                value = vl;
            }


            if (value is QsScalar)
            {
                var scalar = (QsScalar)value;

                QsTensor NewTensor = new QsTensor();
                if (this.Order > 3)
                {
                    foreach (var iTensor in this.InnerTensors)
                    {
                        NewTensor.AddInnerTensor((QsTensor)iTensor.MultiplyOperation(value));
                    }
                }
                else
                {
                    for (int il = 0; il < this.MatrixLayers.Count; il++)
                    {
                        QsMatrix ResultMatrix = (QsMatrix)this.MatrixLayers[il].MultiplyOperation(scalar);
                        NewTensor.AddMatrix(ResultMatrix);
                    }
                }

                return(NewTensor);
            }

            if (value is QsTensor)
            {
                var tensor = (QsTensor)value;
                if (this.Order == 1 && tensor.Order == 1)
                {
                    var thisVec = this[0][0];
                    var thatVec = tensor[0][0];
                    var result  = (QsMatrix)thisVec.TensorProductOperation(thatVec);
                    return(new QsTensor(result));
                }
                if (this.Order == 2 && tensor.Order <= 2)
                {
                    //tenosrial product of two matrices will result in another matrix also.
                    QsMatrix result = (QsMatrix)this.MatrixLayers[0].TensorProductOperation(tensor.MatrixLayers[0]);

                    return(new QsTensor(result));
                }
                else
                {
                    throw new QsException("", new NotImplementedException());
                }
            }

            throw new QsException("Tensor Multiplication Operation with " + value.GetType().Name + " Failed");
        }
예제 #27
0
        public override QsValue SubtractOperation(QsValue vl)
        {
            QsValue value;

            if (vl is QsReference)
            {
                value = ((QsReference)vl).ContentValue;
            }
            else
            {
                value = vl;
            }


            if (value is QsScalar)
            {
                var scalar = value as QsScalar;

                QsTensor NewTensor = new QsTensor();
                if (this.Order > 3)
                {
                    foreach (var iTensor in this.InnerTensors)
                    {
                        NewTensor.SubtractOperation((QsTensor)iTensor.AddOperation(value));
                    }
                }
                else
                {
                    for (int il = 0; il < this.MatrixLayers.Count; il++)
                    {
                        QsMatrix ResultMatrix = (QsMatrix)this.MatrixLayers[il].SubtractOperation(scalar);
                        NewTensor.AddMatrix(ResultMatrix);
                    }
                }
                return(NewTensor);
            }

            if (value is QsTensor)
            {
                var tensor = value as QsTensor;
                if (this.Order != (tensor.Order))
                {
                    throw new QsException("Adding two different ranked tensors are not supported");
                }

                if (this.Order > 3)
                {
                    QsTensor NewTensor = new QsTensor();
                    for (int i = 0; i < this.InnerTensors.Count(); i++)
                    {
                        var iTensor = this.InnerTensors[i];
                        NewTensor.AddInnerTensor((QsTensor)
                                                 iTensor.SubtractOperation(tensor.InnerTensors[i]));
                    }
                    return(NewTensor);
                }
                else
                {
                    if (tensor.MatrixLayers.Count == this.MatrixLayers.Count)
                    {
                        // the operation will succeed
                        if (tensor.FaceRowsCount == this.FaceRowsCount)
                        {
                            if (tensor.FaceColumnsCount == this.FaceColumnsCount)
                            {
                                QsTensor NewTensor = new QsTensor();
                                for (int il = 0; il < this.MatrixLayers.Count; il++)
                                {
                                    QsMatrix ResultMatrix = (QsMatrix)this.MatrixLayers[il].SubtractOperation(tensor.MatrixLayers[il]);
                                    NewTensor.AddMatrix(ResultMatrix);
                                }
                                return(NewTensor);
                            }
                        }
                    }
                }
            }

            throw new QsException("Tensor Subtract Operation with " + value.GetType().Name + " Failed");
        }