1
votes

How to call lpNorm with a templated matrix as input?

Here is the issue from my code:

template<class number>
void normalize_in_place(Matrix<number,Dynamic,Dynamic> & A, level l, axis a){

  const int p = lp_norms::level2pvalue(l);
  switch ( a ) {
    case row: 
      // TODO: get lpnorm working. 
      A = A.transpose().cwiseQuotient(A.rowwise().lpNorm<p>()).transpose();
      //A = A.transpose().cwiseQuotient(A.rowwise().norm()).transpose();
      break;
    case col:
      // TODO: get lpnorm working. 
      //A = A.cwiseQuotient(A.colwise().lpNorm<p>());
      A = A.cwiseQuotient(A.colwise().norm());
      break;
  }
}

Fails during compile with:

error: expected primary expression before [ close parenthesis of lpNorm function ]

where I have substituted the brackets for the arrow you would see on compiler output.

** After refreshing my eigen with the July 23rd release, I get the following error:

error: invalid operands of types ‘’ and ‘const int’ to binary ‘operator<’ A = A.transpose().cwiseQuotient(A.rowwise().lpNorm

()).transpose();

Apparently, lpNorm is not resolving; however, I have included Eigen/Dense, and the standard .norm() works.

No matter which configuration I use, it does not work.

What is the correct way to call the lpNorm?

1
Does rwiseQuotient even exist? Create a Minimal, Complete, and Verifiable example.Lack
@Lack yeah, updated.Chris
That is still not a MCVE (how can anyone compile it without the definitions of level, axis, etc.?) but enough to answer.Lack

1 Answers

5
votes

If you have this code inside a template where the type of A depends on template parameters:

A.rowwise().lpNorm<p>();

The template keyword is needed before a template function:

A.rowwise().template lpNorm<p>();

See Where and why do I have to put the "template" and "typename" keywords?.

Without the template keyword, GCC tries to treat the < in <p> as the less-than operator and produces the error message you see. Clang gives a more helpful error message, error: missing 'template' keyword prior to dependent template name 'lpNorm'.

Also note that the template argument p in lpNorm<p> must be a constant expression (evaluated at compile time). It seems that in your example, lp_norms::level2pvalue(l) will not be a constant expression.