Beispiel #1
0
        /// <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)
            {
                var t = new QsTensor();
                foreach (var m in t.MatrixLayers)
                {
                    t.AddMatrix((QsMatrix)m.DifferentiateOperation(value));
                }
                return(t);
            }
            else
            {
                return(base.DifferentiateOperation(value));
            }
        }
Beispiel #2
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);
        }
Beispiel #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="values">Matrices or Tensors</param>
        /// <returns></returns>
        public static QsValue TensorFromValues(params QsValue[] values)
        {
            QsTensor tens = new QsTensor();

            foreach (var val in values)
            {
                if (val is QsMatrix)
                {
                    tens.AddMatrix((QsMatrix)val);
                }
                else if (val is QsTensor)
                {
                    tens.AddInnerTensor((QsTensor)val);
                }
                else
                {
                    throw new QsException("Component is not a matrix value.");
                }
            }

            return(tens);
        }
Beispiel #4
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);
        }
Beispiel #5
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");
        }
Beispiel #6
0
        public override QsValue GetIndexedItem(QsParameter[] allIndices)
        {
            int[] indices = new int[allIndices.Length];

            for (int ix = 0; ix < indices.Length; ix++)
            {
                indices[ix] = (int)((QsScalar)allIndices[ix].QsNativeValue).NumericalQuantity.Value;
            }

            int dr = this.Order - indices.Count();

            if (dr < 0)
            {
                throw new QsException("Indices count exceed the tensor rank, only specify indices to the same rank to get scalar, or less to get vectors to tensors");
            }
            else if (dr == 0)
            {
                return(GetScalar(indices));
            }
            else if (dr == 1)
            {
                // return vector
                if (this.Order == 2)
                {
                    return(this[0][indices[0]]);
                }
                else if (this.Order == 3)
                {
                    return(this[indices[0]][indices[1]]);
                }
                else
                {
                    QsTensor t  = this;
                    int      ix = 0;
                    int      ic = indices.Count();
                    while (ix < ic - 2)
                    {
                        int idx = indices[ix];
                        if (idx < 0)
                        {
                            idx = t.InnerTensors.Count + idx;
                        }
                        t = t.InnerTensors[idx];
                        ix++;
                    }
                    return(t[indices[ix]][indices[ix + 1]]);  //ix was increased the latest time.
                }
            }
            else if (dr == 2)
            {
                // return matrix;
                if (this.Order == 2)
                {
                    return(this[indices[0]]);
                }
                else
                {
                    // specify the tensor
                    QsTensor t  = this;
                    int      ix = 0;
                    int      ic = indices.Count();
                    while (ix < ic - 1)
                    {
                        int idx = indices[ix];

                        if (idx < 0)
                        {
                            idx = t.InnerTensors.Count + idx;
                        }

                        t = t.InnerTensors[idx];
                        ix++;
                    }



                    // then return the matrix.
                    return(t[indices[ix]]);  //ix was increased the latest time.
                }
            }
            else
            {
                // return tensor
                QsTensor t  = this;
                int      ix = 0;
                while (ix < indices.Count())
                {
                    int idx = indices[ix];
                    if (idx < 0)
                    {
                        idx = t.InnerTensors.Count + idx;
                    }
                    t = t.InnerTensors[idx];
                    ix++;
                }
                return(t);
            }
        }
Beispiel #7
0
        public override QsValue DotProductOperation(QsValue vl)
        {
            QsValue value;

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



            QsTensor tensor;

            if (value is QsTensor)
            {
                tensor = (QsTensor)value;
            }
            else if (value is QsMatrix)
            {
                tensor = new QsTensor((QsMatrix)value);
            }
            else if (value is QsVector)
            {
                tensor = new QsTensor(new QsMatrix((QsVector)value));
            }
            else if (value is QsScalar)
            {
                tensor = new QsTensor(new QsMatrix(new QsVector((QsScalar)value)));
            }
            else
            {
                throw new QsException("Tensor Operation with non mathematical type is not permitted");
            }

            if (tensor == null)
            {
                throw new QsException("Must be a tensor for scalar product");
            }

            if (this.Order > 3)
            {
                throw new NotImplementedException();
            }
            else if (this.Order == 1)
            {
                if (tensor.Order == 1)
                {
                    var thisVec = this[0][0];
                    var thatVec = tensor[0][0];
                    var result  = (QsScalar)thisVec.DotProductOperation(thatVec);
                    return(new QsTensor(new QsMatrix(new QsVector(result))));
                }
            }
            else if (this.Order == 2)
            {
                // only for tensors that looks like matrix.

                // reference:  http://people.rit.edu/pnveme/EMEM851n/constitutive/tensors_rect.html
                // the scalar product called there as double dot  ':'  and I don't know if this is right or wrong
                //

                /*
                 *
                 * if (tensor.Order == 2)
                 * {
                 *  var matrix = tensor.MatrixLayers[0];
                 *  var thisMatrix = this.MatrixLayers[0];
                 *  if (thisMatrix.RowsCount == matrix.RowsCount && thisMatrix.ColumnsCount == matrix.ColumnsCount)
                 *  {
                 *      QsScalar Total = default(QsScalar);
                 *
                 *      for (int i = 0; i < thisMatrix.RowsCount; i++)
                 *      {
                 *          for (int j = 0; j < thisMatrix.ColumnsCount; j++)
                 *          {
                 *              if (Total == null) Total = thisMatrix[i, j] * matrix[j, i];
                 *              else Total = Total + thisMatrix[i, j] * matrix[j, i];
                 *          }
                 *      }
                 *      return Total;
                 *  }
                 *  else
                 *  {
                 *      throw new QsException("The two matrices should be equal in rows and columns");
                 *  }
                 * }
                 */
            }

            throw new NotImplementedException();
        }
Beispiel #8
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");
        }
Beispiel #9
0
        /// <summary>
        /// Initiate adding tensor in current tensor
        /// and increase the rank of the tensor
        /// most probably inserting tensor as a sub tensor will increase rank starting from 4th rank.
        /// </summary>
        /// <param name="qsTensor"></param>
        public void AddInnerTensor(QsTensor qsTensor)
        {
            if (qsTensor.Order == 0)
            {
                if (MatrixLayers.Count == 0)
                {
                    var matrix = new QsMatrix(new QsVector(qsTensor.MatrixLayers[0][0, 0]));

                    MatrixLayers.Add(matrix);
                }
                else
                {
                    // successive insertion of zero rank tensor will be put into the vecor in the matrix in the tensor.
                    MatrixLayers[0].Rows[0].AddComponent(qsTensor.MatrixLayers[0][0, 0]);
                }
            }
            else if (qsTensor.Order == 1)
            {
                if (MatrixLayers.Count == 0)
                {
                    var matrix = new QsMatrix(qsTensor.MatrixLayers[0].Rows[0]);
                    MatrixLayers.Add(matrix);
                }
                else
                {
                    // successive insertion of first rank tensor insert them in the matrix.

                    var v = qsTensor.MatrixLayers[0].Rows[0];

                    if (MatrixLayers.Count > 0)
                    {
                        if (v.Count != this.FaceColumnsCount)
                        {
                            throw new QsInvalidInputException("Adding first rank tensor with different number of columns");
                        }
                    }
                    MatrixLayers[0].AddVector(v);
                }
            }
            else if (qsTensor.Order == 2)
            {
                var matrix = QsMatrix.CopyMatrix(qsTensor.MatrixLayers[0]);

                if (MatrixLayers.Count > 0)
                {
                    if (matrix.RowsCount == this.FaceRowsCount)
                    {
                        if (matrix.ColumnsCount == this.FaceColumnsCount)
                        {
                        }
                        else
                        {
                            throw new QsInvalidOperationException("Adding Second Rank tensor with different number of columns");
                        }
                    }
                    else
                    {
                        throw new QsInvalidOperationException("Adding Second Rank tensor with different number of rows");
                    }
                }
                MatrixLayers.Add(matrix);
            }
            else
            {
                // Third rank tensor or more
                if (InnerTensors == null)
                {
                    InnerTensors = new List <QsTensor>();
                }

                InnerTensors.Add(qsTensor);
            }
        }