This forum has been archived. All content is frozen. Please use KDE Discuss instead.

Rowwise array multiplication/division

Tags: None
(comma "," separated)
navneetdalal
Registered Member
Posts
2
Karma
0
Can someone point if I am doing anything wrong here, or is it just that * and division operations are currently not defined row & column wise?

#include <iostream>
#include <Eigen/Core>
int main()
{
Eigen::ArrayXXf a(2,4);
a << 1, 2, 3, 4,
6, 7, 8, 9;

Eigen::ArrayXf max = a.colwise().maxCoeff();
a.rowwise()-=max;//Compiles & Works
a.rowwise()/=max;//Compilation error
return 0;
}
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
You can do this as a standard matrix product (the .matrix() are to move to the linear algebra world):

a.matrix() = max.matrix().asDiagonal().inverse() * a.matrix()

The main reason that operator / and * are not yet in row/colwise is because we have to make them available only in the array world.

Note that diagonal matrix product and inversion are optimized.
navneetdalal
Registered Member
Posts
2
Karma
0
Hi, I tried this solution. It seems to be 7x slower than writing a for loop per row with llvm-gcc 4.2 on mac. My array has four columns of float. So every row is perfectly aligned.
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
make sure you bench with optimization enabled -O2 -DNDEBUG
daviddoria
Registered Member
Posts
46
Karma
0
OS
Is there a reason why this wouldn't work in place?

Code: Select all
  Eigen::MatrixXf m(2,3);
  m(0,0) = 1;   m(0,1) = 2;   m(0,2) = 3;
  m(1,0) = 4;   m(1,1) = 5;   m(1,2) = 6;

  std::cout << "m: " << m << std::endl;

  // Want to see that the first row remains the same, while the second row is divided by 2
  Eigen::VectorXf v(2);
  v[0] = 1;
  v[1] = 2;

  // This works
  Eigen::MatrixXf m2 = v.matrix().asDiagonal().inverse() * m;
  std::cout << "m2: " << m2 << std::endl;

  // This does not seem to work properly?
  Eigen::MatrixXf m3 = m;
  std::cout << "m3: " << m3 << std::endl;
  m3 *= v.matrix().asDiagonal().inverse();
  std::cout << "m3: " << m3 << std::endl;


The output is
Code: Select all
m2:   1   2   3
  2 2.5   3
m3:   1   1 inf
  4 2.5 inf
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
if you compile with -DNDEBUG, you should get your answer: m3 *= d is equivalent to m3 = m3 * d, however here m3 is 2x3 and d 2x2....


Bookmarks



Who is online

Registered users: Baidu [Spider], Bing [Bot], Google [Bot], rblackwell