- changed status to resolved
Assigning vectors to columns of matrices
Hello! I’ve been trying to convert a bunch of my Armadillo code into Blaze, and one method I can’t seem to do efficiently is replacing the columns of a matrix with a vector. I have pasted my Armadillo code (which works) and the Blaze code which I can’t seem to find the right methods for:
I think essentially, I’m looking for methods to replace one whole column/row of a matrix with a vector (provided that the sizes are matching up perfectly). Any feedback would be super helpful!! Thanks!!
//// We have two matrices: mat_x and mat_y as inputs, and num_facts as in 'int' niput
// Allocate output matrix
arma::mat outmat(mat_x.n_rows, num_facts);
// We loop over num_facts
for (int x = 1; x < num_facts + 1; x++) {
// Remove the x'th factor from input matrix
//// We need to make a copy since shed_col() is in-place
arma::mat xshed = mat_x;
arma::mat yshed = mat_y;
xshed.shed_col(x - 1);
yshed.shed_col(x - 1);
///// The function ArmaInnerSum_ returns a column vector
//// Compute ArmaInnerSum_ and assign that output vector to
//// column 'x-1' of outmat
outmat.col(x - 1) = ArmaInnerSum_(num_facts, xshed, yshed);
//// Compute diff of mat_x and mat_y 's x-1 columns
arma::colvec tmpcol = mat_y.col(x - 1) - mat_x.col(x - 1);
// Multiply x-1th column of outmat with tmpcol element-wise
outmat.col(x - 1) = outmat.col(x - 1) % tmpcol;
}
/////// Blaze implementation ////
// Allocate output matrix
blaze::DynamicMatrix<double> outmat(mat_x.rows(), num_facts);
// Loop over num_facts
for (int x = 1; x < num_facts + 1; x++) {
// Remove the x'th factor from input matrix and
// use over BlazeInnerSum_()
////// I first create a matrix xshed and yshed with being
////// equal to mat_x and mat_y
////// and then I call dropColumnX() on that matrix
////// to drop a column
blaze::DynamicMatrix<double> xshed(mat_x);
blaze::DynamicMatrix<double> yshed(mat_y);
xshed = dropColumnX(xshed, x-1);
yshed = dropColumnX(yshed, x-1);
//// The function BlazeInnerSum_ returns a DynamicVector
blaze::DynamicVector<double> tempvec = BlazeInnerSum_(num_facts, xshed, yshed);
//// So here, instead of a direct assignment of the vector to column x-1
//// of outmat, I loop over outmat and assign the vector element by element
for (int r = 0; r < outmat.rows(); r++) {
// Multiply tempvec with the difference in mat_x and mat_y and column x-1
outmat(r, x - 1) = tempvec[r] * (mat_y(r, x - 1) - mat_x(r, x - 1));
}
}
Comments (3)
-
-
reporter Hey @Klaus Iglberger , thanks a lot for replying. A quick about the right hand side: is it possible to slice the matrix
mat_x
so that instead of looking over the rows ofmat_x
, I can just directly assign the column, something along the lines of:// ... column( outmat, x-1 ) = tempvec * ( column( mat_y ,x-1) ) - column( mat_x, x-1) ); // ...
-
Hi Nafis!
Yes, this is possible. The code you posted should already work: On the right-hand side you create two columns (which correspond to column vectors), subtract them, then perform an element-wise multiplication (which again yields a column vector, assuming that
tempvec
is a column vector) and in the end assign the result to a column ofoutmat
. If you encounter any problem, please ask again.Best regards,
Klaus!
- Log in to comment
Hi Nafis!
In Blaze the tool you need are views, and in particular column views. As the wiki explains, a column can appear on both sides of an assignment: You can use it to read from or to write to a specific column of a matrix. In your example, the column would appear on the left of the assignment:
I hope this helps,
Best regards,
Klaus!