Fixed bug in revealing rank, even simpler than before.
							parent
							
								
									7c045a0802
								
							
						
					
					
						commit
						f5fc14c0f4
					
				|  | @ -301,45 +301,46 @@ void householder_update(Matrix &A, int j, double beta, const Vector& vjm) { | |||
| list<boost::tuple<Vector, double, double> > | ||||
| weighted_eliminate(Matrix& A, Vector& b, const Vector& sigmas) { | ||||
| 	bool verbose = false; | ||||
| 	// get sizes
 | ||||
| 	size_t m = A.size1(); | ||||
| 	size_t n = A.size2(); | ||||
| 	size_t m = A.size1(), n = A.size2(); // get size(A)
 | ||||
| 	size_t maxRank = min(m,n); | ||||
| 
 | ||||
| 	// create list
 | ||||
| 	list<boost::tuple<Vector, double, double> > results; | ||||
| 
 | ||||
| 	// loop over the columns
 | ||||
| 	for (int j=0; j<maxRank; ++j) { | ||||
| 	// We loop over all columns, because the columns that can be eliminated
 | ||||
| 	// are not necessarily contiguous. For each one, estimate the corresponding
 | ||||
| 	// scalar variable x as d-rS, with S the separator (remaining columns).
 | ||||
| 	// Then update A and b by substituting x with d-rS, zero-ing out x's column.
 | ||||
| 	for (int j=0; j<n; ++j) { | ||||
| 		// extract the first column of A
 | ||||
| 		Vector a = column(A, j); | ||||
| 		if (verbose) print(a,"a"); | ||||
| 		if (verbose) print(a,"a = "); | ||||
| 
 | ||||
| 		// find weighted pseudoinverse
 | ||||
| 		// Calculate weighted pseudo-inverse and corresponding precision
 | ||||
| 		Vector pseudo; double precision; | ||||
| 		if (verbose) print(sigmas, "sigmas"); | ||||
| 		boost::tie(pseudo, precision) = weightedPseudoinverse(a, sigmas); | ||||
| 		if (verbose) cout << "precision = " << precision << endl; | ||||
| 
 | ||||
| 		// if precision is zero, rank(A) was less than maxRank, so return
 | ||||
| 		if (precision < 1e-8) { | ||||
| 			maxRank = j; | ||||
| 			return results; | ||||
| 		} | ||||
| 		if (verbose) print(pseudo, "pseudo"); | ||||
| 		// if precision is zero, no information on this column
 | ||||
| 		if (precision < 1e-8) continue; | ||||
| 		if (verbose) print(pseudo, "pseudo = "); | ||||
| 
 | ||||
| 		// create solution and copy into r
 | ||||
| 		Vector r = basis(n, j); | ||||
| 		for (int j2=j+1; j2<n; ++j2) | ||||
| 			r(j2) = inner_prod(pseudo, column(A, j2)); | ||||
| 		if (verbose) print(r, "r = "); | ||||
| 
 | ||||
| 		// create the rhs
 | ||||
| 		double d = inner_prod(pseudo, b); | ||||
| 		if (verbose) print(r, "updatedR"); | ||||
| 		if (verbose) cout << "d = " << d << endl; | ||||
| 
 | ||||
| 		// construct solution (r, d, sigma)
 | ||||
| 		results.push_back(boost::make_tuple(r, d, 1./sqrt(precision))); | ||||
| 
 | ||||
| 		// exit after rank exhausted
 | ||||
| 		if (results.size()>=maxRank) break; | ||||
| 
 | ||||
| 		// update A, b
 | ||||
| 		for (int i=0;i<m;++i) { // update all rows
 | ||||
| 			double ai = a(i); | ||||
|  | @ -347,9 +348,8 @@ weighted_eliminate(Matrix& A, Vector& b, const Vector& sigmas) { | |||
| 			for (int j2=j+1;j2<n;++j2) // limit to only columns in separator
 | ||||
| 				A(i,j2) -= ai*r(j2); | ||||
| 		} | ||||
| 		if (verbose) print(A, "updatedA"); | ||||
| 		//if (verbose) print(sub(A, 0,m, j+1,n), "updatedA"); // bad index
 | ||||
| 
 | ||||
| 		if (verbose) print(sub(A,0,m,j+1,n), "updated A"); | ||||
| 		if (verbose) print(b, "updated b "); | ||||
| 	} | ||||
| 
 | ||||
| 	return results; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue