/// <summary> /// Performs an element wise operation on the input Matrix. /// </summary> /// <param name="m">Matrix.</param> /// <param name="fnElementWiseOp">Function to update each cell specified by the value and cell coordinates.</param> /// <returns>A Matrix.</returns> public static Matrix Each(Matrix m, Func <double, int, int, double> fnElementWiseOp) { var copy = m.Copy(); for (int i = 0; i < m.Rows; i++) { for (int j = 0; j < m.Cols; j++) { copy[i, j] = fnElementWiseOp(copy[i, j], i, j); } } return(copy); }
/// <summary>Cholesky Factorization of a Matrix.</summary> /// <exception cref="InvalidOperationException">Thrown when the requested operation is invalid.</exception> /// <exception cref="SingularMatrixException">Thrown when a Singular Matrix error condition occurs.</exception> /// <param name="m">Input Matrix.</param> /// <returns>Cholesky Faxtorization (R.T would be other matrix)</returns> public static Matrix Cholesky(Matrix m) { if (m.Rows != m.Cols) { throw new InvalidOperationException("Factorization requires a symmetric positive semi-definite matrix!"); } int n = m.Rows; Matrix A = m.Copy(); for (int k = 0; k < n; k++) { if (A[k, k] <= 0) { throw new SingularMatrixException("Matrix is not symmetric positive semi-definite!"); } A[k, k] = System.Math.Sqrt(A[k, k]); for (int j = k + 1; j < n; j++) { A[j, k] = A[j, k] / A[k, k]; } for (int j = k + 1; j < n; j++) { for (int i = j; i < n; i++) { A[i, j] = A[i, j] - A[i, k] * A[j, k]; } } } // put back zeros... for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { A[i, j] = 0; } } return(A); }
/// <summary>Modified Gram-Schmidt QR Factorization.</summary> /// <param name="A">Matrix A.</param> /// <returns>Tuple(Q, R)</returns> public static Tuple <Matrix, Matrix> QR(Matrix A) { int n = A.Rows; Matrix R = Zeros(n); Matrix Q = A.Copy(); for (int k = 0; k < n; k++) { R[k, k] = Q[k, VectorType.Col].Norm(); Q[k, VectorType.Col] = Q[k, VectorType.Col] / R[k, k]; for (int j = k + 1; j < n; j++) { R[k, j] = Vector.Dot(Q[k, VectorType.Col], A[j, VectorType.Col]); Q[j, VectorType.Col] = Q[j, VectorType.Col] - (R[k, j] * Q[k, VectorType.Col]); } } return(new Tuple <Matrix, Matrix>(Q, R)); }
/// <summary>Sorts this object.</summary> private void Sort() { //ordering var eigs = A.Diag() .Select((d, i) => new Tuple <int, double>(i, d)) .OrderByDescending(j => j.Item2) .ToArray(); // sort eigenvectors var copy = V.Copy(); for (var i = 0; i < eigs.Length; i++) { copy[i, VectorType.Col] = V[eigs[i].Item1, VectorType.Col]; } // normalize eigenvectors copy.Normalize(VectorType.Col); V = copy; Eigenvalues = eigs.Select(t => t.Item2).ToArray(); }
/// <summary> /// Performs an element-wise operation on the input Matrices. /// </summary> /// <param name="m1">First Matrix.</param> /// <param name="m2">Second Matrix.</param> /// <param name="fnElementWiseOp">Operation to perform on the value from the first and second matrices.</param> /// <returns>A Matrix.</returns> public static Matrix Each(Matrix m1, Matrix m2, Func <double, double, double> fnElementWiseOp) { if (m1.Rows != m2.Rows) { throw new InvalidOperationException("The row dimensions do not match"); } if (m1.Cols != m2.Cols) { throw new InvalidOperationException("The column dimensions do not match"); } var copy = m1.Copy(); for (int i = 0; i < m1.Rows; i++) { for (int j = 0; j < m1.Cols; j++) { copy[i, j] = fnElementWiseOp(m1[i, j], m2[i, j]); } } return(copy); }
/// <summary>Generate Linear Regression model based on a set of examples.</summary> /// <param name="x">The Matrix to process.</param> /// <param name="y">The Vector to process.</param> /// <returns>Model.</returns> public override IModel Generate(Matrix x, Vector y) { // create initial theta var theta = Vector.Ones(x.Cols + 1); var copy = x.Copy(); // normalise features for (var i = 0; i < copy.Cols; i++) { var j = FeatureNormalizer.FeatureScale(copy[i, VectorType.Col]); for (var k = 0; k < copy.Rows; k++) { copy[k, i] = j[k]; } } // add intercept term copy = copy.Insert(Vector.Ones(copy.Rows), 0, VectorType.Col); // run gradient descent var run = GradientDescent.Run( theta, copy, y, this.MaxIterations, this.LearningRate, new LinearCostFunction(), this.Lambda, new Regularization()); // once converged create model and apply theta var model = new LinearRegressionModel(x.Mean(VectorType.Row), x.StdDev(VectorType.Row)) { Descriptor = this.Descriptor, Theta = run.Item2 }; return model; }
/// <summary>Constructor.</summary> /// <param name="a">The int to process.</param> public Evd(Matrix a) { A = a.Copy(); V = Matrix.Identity(A.Rows); }
/// <summary>Constructor.</summary> /// <param name="a">The int to process.</param> public Evd(Matrix a) { this.A = a.Copy(); this.V = Matrix.Identity(this.A.Rows); }