vector of maps

Hi,

What am I doing wrong here?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <vector>
#include <map>

using namespace std;

int main() {
    vector< map< int, double>* > M;
    M.resize( 10 );

    for( int i=0; i < M.size(); ++i ) {
        M[ i ] = new map<int,double>;
        M[ i ][ i ] = 0.0;    <<<<<<<<<< error
    }
}


Produces:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
junk.cpp(12) : error C2679: binary '=' : 
no operator found which takes a right-hand operand of type 'double' 
(or there is no acceptable conversion)

C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\Include\map(176): 
could be 'std::map<_Kty,_Ty> &std::map<_Kty,_Ty>::operator 
=(const std::map<_Kty,_Ty> &)'
        with
        [
            _Kty=int,
            _Ty=double
        ]
        while trying to match the argument list '(std::map<_Kty,_Ty>, double)'
        with
        [
            _Kty=int,
            _Ty=double
        ]


Why?

Cheers, Buk.
Last edited on
M[i] is a pointer, and the pointer does not have the [] operator. Try to modify line 12 like:
(*M[ i ])[ i ] = 0.0;
Thanks for the quick response, ats15. That works.

However, it's not the nicest syntax; is there some way to avoid the explicit dereference?

I tried:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#pragma warning(disable:4530)
#include <vector>
#include <map>

using namespace std;

int main() {
    vector< map< int, double>& > M;
    M.resize( 10 );

    for( int i=0; i < M.size(); ++i ) {
        M[ i ] = new map<int,double>;
        M[ i ][ i ] = 0.0;
    }
}


But that produces reams of garbage (that I'll post if requested) from within the headers files.

Cheers, Buk.
Is there a reason why the maps are created with new? Can't you simply have a vector of maps without using pointers/references?

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <vector>
#include <map>

using namespace std;

int main() {
    vector< map< int, double> > M;
    M.resize( 10 );

    for( int i=0; i < M.size(); ++i ) {
        M[ i ][ i ] = 0.0;
    }
}


Last edited on
Why use pointers?


Cos what you've posted is...is...is...just too simple.

That couldn't possibly work in verbosity oriented language like C++ :)

(Thanks. That's what I was after, and thought I had tried, but apparently not. )

Cheers, Buk.
That couldn't possibly work in verbosity oriented language like C++ :)


If your C++ is verbose, you're either writing something complicated and unusual, or you're "doing it wrong", as they say. It's common for beginners to write excessive code because they haven't yet learned the standard library.
If your C++ is verbose, you're either writing something complicated and unusual, or you're "doing it wrong", as they say


Hm. That was mostly humour, but since you took it seriously...

I'm trying to optimise some code that does some heavy work with sparse matrix.

The original code uses a hand-code linked list for the sparse part of the matrix; and I thought I try replacing it with a "tried and tested" library routine, using maps.

This code from the original (circa 2000) code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void CBigLinProb::MultA( valarray<double> &X, valarray<double> &Y ) {
    const int nn = n;
    CEntry *e;

    for( int i=0; i < nn; i++ ) Y[ i ] = 0;

    for( int i=0; i < nn; i++ ){
        Y[ i ] += M[ i ]->x * X[ i ];
        e = M[ i ]->next;
        while( e != NULL ) {
            Y[ i ] += e->x * X[ e->c ];
            Y[ e->c ] += e->x * X[ i ];
            e = e->next;
        }
    }
}


became:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void CBigLinProb::MultA( valarray<double> &X, valarray<double> &Y ) {

    for( int i=0; i < MM.size(); i++ ) Y[ i ] = 0;

    for( int i=0; i < MM.size(); i++ ){
        map<int,double> s = MM[ i ];
        Y[ i ] += s[ i ] * X[ i ];

        for( map<int,double>::iterator it=s.begin(); it != s.end(); ++it ) {
            Y[ i ] += it->second * X[ it->first ] * LAMBDA;
            Y[ it->first ] += it->second * X[ i ];
        }
    }
}


And the result is that the original run time of 11.473 seconds became 166.939 seconds.

Yes. I know that with C++11, those loop iterator definitions can be simplified with auto; but C++11 isn't an option; and it doesn't simplify it that much.

And damn! Is it ever slow!
I took some fast code, and I replaced big pieces of it with code I knew was slower, and now it's slower. OMG.

for( int i=0; i < MM.size(); i++ ) Y[ i ] = 0;
What's that for? The value never gets read.

What does this have to do with verbose? Neither of those pieces of code are particularly verbose.
Last edited on
I took some fast code, and I replaced big pieces of it with code I knew was slower, and now it's slower
.

I didn't know it was slower; but I do now.

You don't find for( map<int,double>::iterator it=s.begin(); verbose? Take a look at the equivalent in D.

Thanks for your contributions.
Your passive-aggressive tone is childish and pathetic. Grow up. If you're capable of genuine discussion, do it. If not, take it back to the playground.
Last edited on
for( int i=0; i < MM.size(); i++ ) Y[ i ] = 0;
What's that for? The value never gets read.


You didn't notice this?:
1
2
Y[ it->first ] += it->second * X[ i ];
//.............^^ 
Last edited on
Topic archived. No new replies allowed.