public static VectorC operator *(double d, VectorC v) { VectorC result = new VectorC(v.size); for (int i = 0; i < v.size; i++) { result[i] = d * v[i]; } return result; }
public static VectorC operator *(VectorC v, double d) { VectorC result = new VectorC(v.size); for (int i = 0; i < v.size; i++) { result[i] = v[i] * d; } return result; }
public static MatrixC operator *(MatrixC m1, MatrixC m2) { if (m1.GetCols()!=m2.GetRows()) { throw new ArgumentOutOfRangeException( "Columns", m1, "The numbers of columns of the first matrix must be equal to" + " the number of rows of the second matrix!"); } MatrixC result = new MatrixC(m1.GetRows(), m2.GetCols()); VectorC v1 = new VectorC(m1.GetCols()); VectorC v2 = new VectorC(m2.GetRows()); for (int i = 0; i < m1.GetRows(); i++) { v1 = m1.GetRowVector(i); for (int j = 0; j < m2.GetCols(); j++) { v2 = m2.GetColVector(j); result[i, j] = VectorC.DotProduct(v1, v2); } } return result; }
/// <summary> /// Implementation Convex optimization using ADMM( Stephen Boyd, Stanford) It is essentially least squares fitting with non-negativity constraints /// An ANOVA computation is added below for significance testing although this implementation is NOT VALIDATED /// The matrix is any reference matrix (database) and y is the experimental data. The result is a vector of coefficients for the model /// </summary> /// <param name="matrix"></param> /// <param name="y"></param> /// <returns></returns> public VectorC MatchLibraryMatrix(MatrixC matrix, VectorC y) { #region ADMM (Alternating direction method of multipliers) //regularized matrix version of least squares //x = (A'*A)*A'*b //rho, the wiggle factor double rho = .001; //Ax = b where x is the prediction, b is the experimental and A is the reference database matrix // A = x^t*x var A = matrix.Transpose() * matrix; //b = xt*y MatrixC y1 = new MatrixC(matrix.GetRows(), 1); y1.ReplaceCol(y, 0); var temp1 = matrix.Transpose() * y1; VectorC b = new VectorC(temp1.GetRows()); for(int i = 0; i < temp1.GetRows();i++) { b[i] = temp1[i,0]; } //create identity matrix var I = A.Identity(); //A' = (A + rho*I) var Aprime = MatrixC.Inverse(A + (rho * I)); double[] components = new double[b.GetSize()]; //add zeros to vectors for (int i = 0; i < b.GetSize(); i++) { components[i] = 0; } VectorC u = new VectorC(components); //accululated error in the negative direction VectorC z = new VectorC(components); //non-negative version of x VectorC x = new VectorC(components); //regularized least squares u = u.Clone(); z = z.Clone(); x = x.Clone(); double sumSquares = 0; for (int i = 0; i < 1500; i++) { x = MatrixC.Transform(Aprime, (b + rho * (z - u))); //for each element in x + u //z = (x + u); for (int j = 0; j < x.GetSize(); j++) { var temp = x[j] + u[j]; if (temp > 0) { z[j] = temp; } else { z[j] = 0; } } if (i == 1499) { int test11 = 0; } //for each element in x - z // u = u + (x - z); for (int k = 0; k < u.GetSize(); k++) { u[k] = u[k] + (x[k] - z[k]); } //calculate RMS error for (int ii = 0; ii < x.GetSize(); ii++) { sumSquares += (x[ii] - z[ii])*(x[ii] - z[ii]); } var RMS = Math.Sqrt(sumSquares / x.GetSize()); if (RMS < .001) { break; } } #endregion #region ANOVA //Matrix yMatrix = Matrix.Create(y); //Matrix database = (m.Transpose()*m).GetInverse()*m.Transpose(); ////ADMM //var predicted = m*z; ////Hat matrix. The hat matrix is used to reduce overfitting by finding outliers ////inv(x'*x)*x'*x' //var hatMatrix = (m*(m.Transpose()*m).GetInverse())*m.Transpose(); ////J matrix square matrix of ones //Matrix JMatrix = Matrix.Create(hatMatrix.ColumnCount, hatMatrix.RowCount); //for (int i = 0; i < JMatrix.ColumnCount; i++) //{ // for (int j = 0; j < JMatrix.RowCount; j++) // { // JMatrix[i, j] = 1; // } //} ////SSr (2000 is the observations or m/z in our case) ////y'*[H - (1/n)J]*y //var SSr = Y.Transpose()*((hatMatrix - (1/2000)*JMatrix))*Y; ////Mean Square Regression //var MSR = SSr/matrix.GetLongLength(1); ////Identity matrix //// The following constructs a nxn identity matrix: //DenseMatrix identityMatrix = DenseMatrix.GetIdentity(2001); ////SSE ////y'*[I-H]*y //var SSe = Y.Transpose()*(identityMatrix - hatMatrix)*Y; //double MSquareRegression = MSR[0, 0]; ////Mean Square Error //var MSE = SSe/(2000 - (matrix.GetLongLength(1) + 1)); //double MSquareError = MSE[0, 0]; ////F-statistic ////The fstat conducts a hypothesis test. It simply says, is there at least one coefficient that ////id different than zero? //var f = MSquareRegression/MSquareError; ////get covariance matrix //var C = MSquareError*(m.Transpose()*m).GetInverse(); ////get diangonal //var d = C.GetDiagonal(); ////conduct t-test for all coefficients (vectorResult for OLS) //for (int i = 0; i < z.Length; i++) //{ // double tTest = z[i]/Math.Sqrt(d[i]); //} ////populate correlation scores (vectorResult for OLS) //for (int i = 0; i < z.Length; i++) //{ //} #endregion return z; }
public static VectorC operator +(VectorC v1, VectorC v2) { VectorC result = new VectorC(v1.size); for (int i = 0; i < v1.size; i++) { result[i] = v1[i] + v2[i]; } return result; }
public VectorC GetUnitVector() { VectorC result = new VectorC(vector); result.Normalize(); return result; }
public bool Equals(VectorC v) { return vector == v.vector; }
public VectorC Clone() { // returns a deep copy of the vector VectorC v = new VectorC(vector); v.vector = (double[])vector.Clone(); return v; }
public static VectorC TriVectorProduct(VectorC v1, VectorC v2, VectorC v3) { if (v1.size != 3) { throw new ArgumentOutOfRangeException( "v1", v1, "Vector v1 must be 3 dimensional!"); } if (v1.size != 3) { throw new ArgumentOutOfRangeException( "v2", v2, "Vector v2 must be 3 dimensional!"); } if (v1.size != 3) { throw new ArgumentOutOfRangeException( "v3", v3, "Vector v3 must be 3 dimensional!"); } return v2 * VectorC.DotProduct(v1, v3) - v3 * VectorC.DotProduct(v1, v2); }
public static double TriScalarProduct(VectorC v1, VectorC v2, VectorC v3) { if (v1.size != 3) { throw new ArgumentOutOfRangeException( "v1", v1, "Vector v1 must be 3 dimensional!"); } if (v1.size != 3) { throw new ArgumentOutOfRangeException( "v2", v2, "Vector v2 must be 3 dimensional!"); } if (v1.size != 3) { throw new ArgumentOutOfRangeException( "v3", v3, "Vector v3 must be 3 dimensional!"); } double result = v1[0] * (v2[1] * v3[2] - v2[2] * v3[1]) + v1[1] * (v2[2] * v3[0] - v2[0] * v3[2]) + v1[2] * (v2[0] * v3[1] - v2[1] * v3[0]); return result; }
public static double DotProduct(VectorC v1, VectorC v2) { double result = 0.0; for (int i = 0; i < v1.size; i++) { result += v1[i] * v2[i]; } return result; }
public static VectorC CrossProduct(VectorC v1, VectorC v2) { if (v1.size != 3) { throw new ArgumentOutOfRangeException( "v1", v1, "Vector v1 must be 3 dimensional!"); } if (v2.size != 3) { throw new ArgumentOutOfRangeException( "v2", v2, "Vector v2 must be 3 dimensional!"); } VectorC result = new VectorC(3); result[0] = v1[1] * v2[2] - v1[2] * v2[1]; result[1] = v1[2] * v2[0] - v1[0] * v2[2]; result[2] = v1[0] * v2[1] - v1[1] * v2[0]; return result; }
public MatrixC ReplaceRow(VectorC v, int n) { if (n < 0 || n > Rows) { throw new ArgumentOutOfRangeException( "n", n, "n is out of range!"); } if (v.GetSize() != Cols) { throw new ArgumentOutOfRangeException( "Vector size", v.GetSize(), "vector size is out of range!"); } for (int i = 0; i < Cols; i++) { matrix[n, i] = v[i]; } return new MatrixC(matrix); }
public VectorC GetRowVector(int n) { if (n < 0 || n > Rows) { throw new ArgumentOutOfRangeException( "n", n, "n is out of range!"); } VectorC v = new VectorC(Cols); for (int i = 0; i < Cols; i++) { v[i] = matrix[n, i]; } return v; }
public static MatrixC Transform(VectorC v1, VectorC v2) { if (v1.GetSize() != v2.GetSize()) { throw new ArgumentOutOfRangeException( "v1", v1.GetSize(), "The vectors must have the same size!"); } MatrixC result = new MatrixC(v1.GetSize(), v1.GetSize()); for (int i = 0; i < v1.GetSize(); i++) { for (int j = 0; j < v1.GetSize(); j++) { result[j, i] = v1[i] * v2[j]; } } return result; }
public static VectorC Transform(VectorC v, MatrixC m) { VectorC result = new VectorC(v.GetSize()); //if (!m.IsSquared()) //{ // throw new ArgumentOutOfRangeException( // "Dimension", m.GetRows(), "The matrix must be squared!"); //} //if (m.GetRows() != v.GetSize()) //{ // throw new ArgumentOutOfRangeException( // "Size", v.GetSize(), "The size of the vector must be equal" // + "to the number of rows of the matrix!"); //} for (int i = 0; i < m.GetRows(); i++) { result[i] = 0.0; for (int j = 0; j < m.GetCols(); j++) { result[i] += v[j] * m[j, i]; } } return result; }