public virtual bool decompose(FMatrixRBlock orig) { if (orig.numCols != orig.numRows) { throw new ArgumentException("Input matrix must be square."); } init(orig); FSubmatrixD1 subA = new FSubmatrixD1(A); FSubmatrixD1 subV = new FSubmatrixD1(V); FSubmatrixD1 subU = new FSubmatrixD1(A); int N = orig.numCols; for (int i = 0; i < N; i += A.blockLength) { // Console.WriteLine("-------- triag i "+i); int height = Math.Min(A.blockLength, A.numRows - i); subA.col0 = subU.col0 = i; subA.row0 = subU.row0 = i; subU.row1 = subU.row0 + height; subV.col0 = i; subV.row1 = height; subV.original.reshape(subV.row1, subV.col1, false); // bidiagonalize the top row TridiagonalHelper_FDRB.tridiagUpperRow(A.blockLength, subA, gammas, subV); // apply Householder reflectors to the lower portion using block multiplication if (subU.row1 < orig.numCols) { // take in account the 1 in the last row. The others are skipped over. float before = subU.get(A.blockLength - 1, A.blockLength); subU.set(A.blockLength - 1, A.blockLength, 1); // A = A + U*V^T + V*U^T multPlusTransA(A.blockLength, subU, subV, subA); multPlusTransA(A.blockLength, subV, subU, subA); subU.set(A.blockLength - 1, A.blockLength, before); } } return(true); }