public static List<int> qrDecomposition(Matrix M, Matrix q, Matrix r, bool pivot)
{
Matrix mT = Matrix.transpose(M);
int m = M.rows();
int n = M.columns();
List<int> lipvt = new InitializedList<int>(n);
Vector rdiag = new Vector(n);
Vector wa = new Vector(n);
MINPACK.qrfac(m, n, mT, 0, (pivot)?1:0, ref lipvt, n, ref rdiag, ref rdiag, wa);
if (r.columns() != n || r.rows() !=n)
r = new Matrix(n, n);
for (int i=0; i < n; ++i) {
// std::fill(r.row_begin(i), r.row_begin(i)+i, 0.0);
r[i, i] = rdiag[i];
if (i < m) {
// std::copy(mT.column_begin(i)+i+1, mT.column_end(i),
// r.row_begin(i)+i+1);
}
else {
// std::fill(r.row_begin(i)+i+1, r.row_end(i), 0.0);
}
}
if (q.rows() != m || q.columns() != n)
q = new Matrix(m, n);
Vector w = new Vector(m);
//for (int k=0; k < m; ++k) {
// std::fill(w.begin(), w.end(), 0.0);
// w[k] = 1.0;
// for (int j=0; j < Math.Min(n, m); ++j) {
// double t3 = mT[j,j];
// if (t3 != 0.0) {
// double t
// = std::inner_product(mT.row_begin(j)+j, mT.row_end(j),
// w.begin()+j, 0.0)/t3;
// for (int i=j; i<m; ++i) {
// w[i]-=mT[j,i]*t;
// }
// }
// q[k,j] = w[j];
// }
// std::fill(q.row_begin(k) + Math.Min(n, m), q.row_end(k), 0.0);
//}
List<int> ipvt = new InitializedList<int>(n);
//if (pivot) {
// std::copy(lipvt.get(), lipvt.get()+n, ipvt.begin());
//}
//else {
// for (int i=0; i < n; ++i)
// ipvt[i] = i;
//}
return ipvt;
}