The best way to store some data in a matrix



  • Hi all,
    I need to store some data in a matrix of 5 column .
    The data are retrieved in run-time from a GUI (not so important at this time).

    Before I needed a 2 columns matrix (an integer and a string) so I solved it this way:
    @
    QList<QPair<int, QString> > myMatrix2d;
    ...
    ...
    @

    Now with 5 columns I don't know how to proceed...

    Some ideas...?



  • If you just need five columns, you could possibly create your matrix as a list of arrays, something like:

    @QList<QVariant*> matrix@

    if every list item contains an array of size 5 you'll have five columns. Furthermore if you'r matrix is static (like 5x5 matrix) you may implement it as an more dimensional array only, without any QList.



  • One general way would be to do it as follows:
    @
    QList< QList<data> > matrix;
    @
    where data represents the data type to store, in general QVariant.

    If you have always the same types and know the types before implementing, I would make a structure for one row, like this:

    @
    struct MyRow
    {
    int first;
    QString second;
    QDateTime third;
    ...
    }

    QList< MyRow > matrix;
    

    @



  • Please do not use C style arrays in Qt or in C++ in general. It is almost always not what you want! The container classes of Qt, stdlib or boost are easier to use and much more save!

    You can easily achieve something similar with Qt classes like this:

    @
    QList<QList<QVariant> > matrix;
    @

    Respect the space between the two >, it is a must otherwise the compiler interprets it as operator>> and bails out.

    Though, this solution is suboptimal, as it does not constrain your matrix, i.e. it is not forced to be 5x5, it's not even possible to constraint every inner list to have the same amount of entries.

    I'd propose writing your own small class, with a simple storage, (e.g. QVarLengthArray or QVector). Put all in one single container and calculate the offset like this:

    @
    int matrixSize = 5;
    QVector<MyMatrixEntry> matrixStorage(matrixSize * matrixSize);

    MyMatrixEntry MyMatrix::getEntry(int row, int col)
    {
    int offset = row * matrixSize + col;
    return matrixStorage[offset];
    }
    @



  • Thanks for the solutions,

    I can't use a structure because I also need to to put it in a QBuffer with the << operator :

    @
    QBuffer buffer;
    buffer.open(QBuffer::ReadWrite);
    QDataStream out(&buffer);
    out << myMatrix;
    @

    Probably the best solution is:
    @
    QList<QList<QVariant> > myMatrix;
    @
    but as said Volker I can't be sure of the column number .



  • It's easy to write your own operators for this:

    @
    QDataStream &operator<<(QDataStream &out, const MyMatrix &matrix)
    {
    out << "MyMatrix";
    out << 1; // version
    out << matrix.matrixData;
    return out;
    }

    QDataStream &operator>>(QDataStream &in, MyMatrix &matrix)
    {
    QString label;
    in >> label;
    if(label != "MyMatrix")
    return in;

    int version;
    in >> version;
    if(version != 1)
        return in; // or do some conversion stuff
    
    in >> matrix.matrixData;
    return in;
    

    }
    @

    EDIT: Fixed errors

    PS:
    Don't forget to allow accessing the data members by the operators in your matrix class:

    @
    class MyMatrix {
    friend QDataStream &operator<<(QDataStream &, const MyMatrix &);
    friend QDataStream &operator>>(QDataStream &, MyMatrix &);
    // rest of your class
    };
    @



  • You can use struct/class, because you can overload the operator<< and operator>> and then use that to serialize your struct.

    If you think that your matrix will get big the second solution Volker gave you is better than QList<QList<T> >
    LE: too late, Volker was faster ;)



  • This is interesting...
    So I can implement a MyMatrix class store the data in some way (list, struct ecc..) and implement in it my operators ( <<, >> ) .
    Very useful, Thanks.



  • [quote author="Luca" date="1296653343"]This is interesting...
    So I can implement a MyMatrix class store the data in some way (list, struct ecc..) and implement in it my operators ( <<, >> ) .
    Very useful, Thanks.[/quote]

    That's standard C++ basics. See the "C++ FAQ on Operator Overloading":http://www.parashift.com/c++-faq-lite/operator-overloading.html. You can even create your own + - * and / operators on the matrix.

    I would really suggest to go with your own class, as you can enforce the users to store only 5x5 data. With the lists users can store any arbitrary two dimensional data. There are neither constraints on the number of rows nor the number of columns. Worse, each row can have a different number of columns.



  • [quote author="Volker" date="1296653620"][quote author="Luca" date="1296653343"]This is interesting...
    So I can implement a MyMatrix class store the data in some way (list, struct ecc..) and implement in it my operators ( <<, >> ) .
    Very useful, Thanks.[/quote]

    That's standard C++ basics. See the "C++ FAQ on Operator Overloading":http://www.parashift.com/c++-faq-lite/operator-overloading.html. You can even create your own + - * and / operators on the matrix.

    I would really suggest to go with your own class, as you can enforce the users to store only 5x5 data. With the lists users can store any arbitrary two dimensional data. There are neither constraints on the number of rows nor the number of columns. Worse, each row can have a different number of columns.[/quote]

    Thanks, I know about operator overloading but I never used it. It's time to begin.

    I'll try with my own class.

    Thanks again.



  • Hi Volker...Thanks a lot. I had implemented the same logic but never kept << & >> operator overloading function as friend while declaring it. It works now as expected.

    Thanks again :).



  • I just implemented a set of template classes to implement different types of matrices. Works well for me. It also depends a lot on your use case what approach for a matrix works best. Is your matrix symetric? It is sparse or dense? You need to consider that kind of questions if you build one. Just blindly recommending

    @QList<QList<QVariant> > myMatrix@

    isn't a good idea IMHO.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.