/// <summary> /// Gram-Schmidtian orthogonalization of an m by n matrix A, such that /// {Q, R} is returned, where A = QR, Q is m by n and orthogonal, R is /// n by n and upper triangular matrix. /// </summary> /// <returns></returns> public ArrayMatrix[] QRGramSchmidt() { var m = RowCount; var n = ColumnCount; var A = Clone(); var Q = new ArrayMatrix(m, n); var R = new ArrayMatrix(n, n); // the first column of Q equals the first column of this matrix for (var i = 1; i <= m; i++) Q[i, 1] = A[i, 1]; R[1, 1] = Complex.One; for (var k = 1; k <= n; k++) { R[k, k] = new Complex(A.Column(k).Norm()); for (var i = 1; i <= m; i++) Q[i, k] = A[i, k]/R[k, k]; for (var j = k + 1; j <= n; j++) { R[k, j] = Dot(Q.Column(k), A.Column(j)); for (var i = 1; i <= m; i++) A[i, j] = A[i, j] - Q[i, k]*R[k, j]; } } return new ArrayMatrix[] {Q, R}; }
/// <summary> /// Vertically concats matrices A and B, which do not have to be of the same height. /// </summary> /// <param name="A"></param> /// <param name="B"></param> /// <returns>Matrix [A|B]</returns> public static ArrayMatrix VerticalConcat(ArrayMatrix A, ArrayMatrix B) { var C = A.Column(1); for (var j = 2; j <= A.ColumnCount; j++) C.InsertColumn(A.Column(j), j); for (var j = 1; j <= B.ColumnCount; j++) C.InsertColumn(B.Column(j), C.ColumnCount + 1); return C; }