public IVariable Subtract(IVariable x, GekkoTime t) { //clone this Add() method and do with O.SubtractMatrixScalar, also for Matrix and matrix EVariableType type = x.Type(); if (type == EVariableType.Matrix) { double[,] a = this.data; double[,] b = ((Matrix)x).data; int m = a.GetLength(0); int k = a.GetLength(1); if (b.GetLength(0) != m || b.GetLength(1) != k) { G.Writeln2("*** ERROR: The two matrices are not compatible for subtraction"); G.Writeln2(" " + m + "x" + k + " and " + b.GetLength(0) + "x" + b.GetLength(1) + " do not match"); throw new GekkoException(); } double[,] c = O.SubtractMatrixMatrix(a, b, m, k); Matrix z = new Matrix(); z.data = c; return(z); } else { //subtraction of a scalar is not legal, this is like AREMOS G.Writeln2("*** ERROR: You are trying to add a MATRIX and a " + type.ToString().ToUpper()); throw new GekkoException(); } }
public IVariable Multiply(IVariable x, GekkoTime t) { EVariableType type = x.Type(); if (type == EVariableType.Matrix) { double[,] a = this.data; double[,] b = ((Matrix)x).data; // m x k * p x n int m = a.GetLength(0); int k = a.GetLength(1); int p = b.GetLength(0); int n = b.GetLength(1); if (p == 1 && n == 1) { //Special case, #a * #onebyone double[,] c = O.MultiplyMatrixScalar(a, b[0, 0], m, k); Matrix z = new Matrix(); z.data = c; return(z); } else if (m == 1 && k == 1) { //Special case, #onebyone * #a double[,] c = O.MultiplyMatrixScalar(b, a[0, 0], p, n); Matrix z = new Matrix(); z.data = c; return(z); } else { if (k != p) { G.Writeln2("*** ERROR: The two matrices are not compatible for multiplication"); G.Writeln2(" " + m + "x" + k + " and " + b.GetLength(0) + "x" + b.GetLength(1) + " do not match"); } double[,] c = null; if (false) { c = new double[m, n]; alglib.rmatrixgemm(m, n, k, 1, a, 0, 0, 0, b, 0, 0, 0, 0, ref c, 0, 0); } else { c = Program.MultiplyMatrices(a, b); } Matrix z = new Matrix(); z.data = c; return(z); //c = {{74, 80, 86, 92}, {173, 188, 203, 218}} } } else if (type == EVariableType.Val) { //This is allowed in AREMOS, too double[,] a = this.data; double b = O.GetVal(x, t); int m = a.GetLength(0); int k = a.GetLength(1); double[,] c = O.MultiplyMatrixScalar(a, b, m, k); Matrix z = new Matrix(); z.data = c; return(z); } else { G.Writeln2("*** ERROR: You are trying to multiply a MATRIX and a " + type.ToString().ToUpper()); throw new GekkoException(); } }