简体   繁体   中英

Error in using max function with Armadillo sparse matrices

Here is the code that I am getting error(type mismatch) on line no. with max :

#include <iostream>
#include <stdlib.h>
#include <math.h>
#include<armadillo>  

using namespace std;
using namespace arma;

int main(int argc, char** argv) {
    umat loc;
    loc<<0<<0<<3<<endr
       <<2<<4<<4<<endr;

    vec val={1,2,3};
    sp_mat m(loc,val);

    double t=arma::max(sum(square(m),1)) + 1.0;
    cout<<t<<endl; 
    return 0;
}

Can somebody tell me why is that error happening and how to get around this.
Note: cout<<max(sum(square(m),1)) prints the result to console but adding any number to the output flags error.

If you want to convert a 1x1 matrix into a pure scalar (like double), use the as_scalar() function. Same goes for any Armadillo expression that results in a 1x1 matrix.

It's a good idea to read the Armadillo documentation thoroughly before posting questions on Stackoverflow.

Modifying your example:

umat loc = { { 0, 0, 3 },
             { 2, 4, 4 } };

vec val = {1, 2, 3};

sp_mat m(loc,val);

m.print("m:");

max(sum(square(m),1)).print("expression:");

double t = as_scalar( max(sum(square(m),1)) );

cout << t << endl; 

You haven't told us (and I can't find in the documentation) exactly what data type is returned by arma::max(sum(square(m),1))

You have tested that whatever it is does not implicitly convert to double and whatever it is can be sent to a stream and when that is done it looks like a double .

My guess is it is something that can be explicitly converted to double so try:

(double)arma::max(sum(square(m),1)) + 1.0

The documentation shows the returned value for a dense matrix being used to initialize a double so that is obviously a type than can be explicitly converted to double . I had initially missed the thing you linked for me effectively saying sum does something on sparse matrix compatible with what it does on dense. So you can almost conclude (rather than just guess) that max(sum(m)) should be the same type (explicitly convertible to double ).

If that doesn't work, we will really need a full quote of the error message, not just a summary of what it seems to mean.

Now that we have an error message, we can see this is a flaw in Armadillo's template metaprogramming:

Operations are stacked in template meta programming in order to avoid creating excess temporary objects. Then the meta programming must resolve the whole mess when the result is used.

If this is a minor flaw in the meta programming, you could add just one trivial temporary to fix it:

double t = arma::max(sum(square(m),1));
cout << t+1.0 endl;

But you probably already tried that. So you may need more temporaries and you probably need to give them exact correct types (rather than use auto ). My first guess would be:

colvec v = sum(square(m),1);

Then see what works with arma::max(v)

(Earlier I made a negative comment on an answer that suggested starting with auto temporaries for each step. That answer was deleted. It wasn't far wrong. But I'd still say it was wrong to start there without seeing the template meta-programming failures and likely, though I'm not sure, wrong to use auto to try to bypass a meta-programming failure.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM