Is it possible to create matrixes with vector <vector <double >> ?

Discussion in 'C++' started by LumisROB, Sep 24, 2005.

  1. LumisROB

    LumisROB Guest

    Is it possible to create matrixes with vector <vector <double >> ? If
    it is possible which is the element m23 ?
    You excuse but I am not an expert

    Thanks
    ROB
    LumisROB, Sep 24, 2005
    #1
    1. Advertising

  2. LumisROB

    persenaama Guest

    Assuming that you mean 4x4 matrices as in "Direct3D" or "OpenGL" (the
    m23 is reason for the assumption), yes, you can, but no, you shouldn't.

    Here's alternative you might want to look into further:

    class matrix4x4
    {
    double m[4][4];
    // TODO: writing accessors, constructor, et cetera left as
    // exercise to the reader :)
    };

    If you want to be more generic, maybe something like this:

    template <typename scalar, int xsize, int ysize>
    class matrix
    {
    scalar m[xsize][ysize];
    // same exercise as above..
    };

    What's is it that you really want to achieve? Above is just stab in the
    dark which is kinda gay. Help me, to help you... (where is this quote
    from, anyone? :)
    persenaama, Sep 24, 2005
    #2
    1. Advertising

  3. LumisROB

    benben Guest

    "persenaama" <> wrote in message
    news:...
    > Assuming that you mean 4x4 matrices as in "Direct3D" or "OpenGL" (the
    > m23 is reason for the assumption), yes, you can, but no, you shouldn't.
    >
    > Here's alternative you might want to look into further:
    >
    > class matrix4x4
    > {
    > double m[4][4];
    > // TODO: writing accessors, constructor, et cetera left as
    > // exercise to the reader :)
    > };
    >
    > If you want to be more generic, maybe something like this:
    >
    > template <typename scalar, int xsize, int ysize>
    > class matrix
    > {
    > scalar m[xsize][ysize];
    > // same exercise as above..
    > };
    >
    > What's is it that you really want to achieve? Above is just stab in the
    > dark which is kinda gay. Help me, to help you... (where is this quote
    > from, anyone? :)
    >


    I may disagree with the template approach listed above. While template helps
    produce flexible design, making the dimension of a matrix bundled with type
    at compile time reduces runtime flexibility.

    What if you need a matrix of dimension only known at runtime?

    My approach would be:

    template <typename ElementT, typename AllocatorT>
    class matrix
    {
    public:
    typedef ElementT element_type;
    typedef std::size_t size_type;

    private:
    std::vector<element_type, AllocatorT> repr;
    size_type num_rows;
    size_type num_cols;

    public:
    matrix(size_type r, size_type c);
    size_type row_size(void);
    size_type col_size(void);
    element_type& operator() (size_type r, size_type c);
    const element_type& operator()(size_type r, size_type c) const;

    // ... etc
    };
    benben, Sep 24, 2005
    #3
  4. LumisROB

    persenaama Guest

    No problem, I want to point out that I assumed D3D/GL or similiar
    purpose (however the double is dubious in that context :)
    persenaama, Sep 24, 2005
    #4
  5. LumisROB

    Kai-Uwe Bux Guest

    LumisROB wrote:

    > Is it possible to create matrixes with vector <vector <double >> ?


    Not quite, but

    vector <vector <double > >
    ^^^
    would work.


    > If it is possible which is the element m23 ?


    Do you mean, the entry in row 2 and column 3? Well, that depends on whether
    you think of your vector< vector< double > > as a vector of row-vectors
    vector of column vectors.


    Having said this, let me add:

    Don't roll your own matrix code unless you absolutely have to.

    a) Numerical linear algebra is *hard*: algorithms that you might recall from
    your college linear algebra class routinely run into trouble because
    numbers on a computer like double simply do not obey nice mathematical
    rules. (Small determinants or bad choices for pivots can completely
    obliterate a matrix inversion).

    b) It is difficult to get this kind of code right, and when you have it
    right, it is very hard to make it efficient. The state of the art uses
    heavy templating machinery to avoid unnecessary copy constructions and help
    the compiler unroll those many loops that you are running into.

    c) There is no need for you to reinvent the wheel. Google for C++ linear
    algebra libraries or visit http://www.oonumerics.org.


    Best

    Kai-Uwe Bux
    Kai-Uwe Bux, Sep 24, 2005
    #5
  6. LumisROB

    LumisROB Guest

    On Sat, 24 Sep 2005 10:05:24 GMT, LumisROB
    <> wrote:

    For everobody:

    Thanks for the help!!!

    I apologize you, I have been a little clear but my goodness.. I didn't
    think could enter so many other considerations.

    We see better thing it would serve me:

    1) I would like to find a basic solution (simple for a beginner of
    the c++) of the type double m [..] [..] that however allows me to
    change dimension of the array during the execution of the program


    2) I have to overcome the limitation of the length of the arrays that
    is of 2^31 (also in the environment to 64 bit in which I operate. This
    is due to the fact that the code has to talk with Matlab that has this
    limitation). Someone has told me that for instance making double
    m[2^6][2^6] I succeed in revolving the problem (in an operating system
    to 64 bit even if the compiler is to 32 bit. is it true?)

    For Kay-Uwe Bux

    Thanks of the very beautiful panning indeed. The problem is that some
    classes result to have the 2^31 limitation that I have said above.
    Besides I have to make simple algebraic calculations. Certainly, if I
    didn't have that limitation I would have used some librariez of those
    from you pointed out me


    Thanks for your time
    ROB
    LumisROB, Sep 24, 2005
    #6
  7. LumisROB

    Kai-Uwe Bux Guest

    LumisROB wrote:

    > On Sat, 24 Sep 2005 10:05:24 GMT, LumisROB
    > <> wrote:
    >
    > For everobody:
    >
    > Thanks for the help!!!
    >
    > I apologize you, I have been a little clear but my goodness.. I didn't
    > think could enter so many other considerations.
    >
    > We see better thing it would serve me:
    >
    > 1) I would like to find a basic solution (simple for a beginner of
    > the c++) of the type double m [..] [..] that however allows me to
    > change dimension of the array during the execution of the program
    >
    >
    > 2) I have to overcome the limitation of the length of the arrays that
    > is of 2^31 (also in the environment to 64 bit in which I operate. This
    > is due to the fact that the code has to talk with Matlab that has this
    > limitation). Someone has told me that for instance making double
    > m[2^6][2^6] I succeed in revolving the problem (in an operating system
    > to 64 bit even if the compiler is to 32 bit. is it true?)
    >
    > For Kay-Uwe Bux
    >
    > Thanks of the very beautiful panning indeed. The problem is that some
    > classes result to have the 2^31 limitation that I have said above.
    > Besides I have to make simple algebraic calculations. Certainly, if I
    > didn't have that limitation I would have used some librariez of those
    > from you pointed out me


    Hm, looks like you absolutely need to roll your own code.

    May I ask what size of matrices you expect to typically run into? Also, do
    your matrices have a special shape (like upper triangular) or are most of
    the entries 0 for some other reason? I am asking since using some
    simple-minded allocation strategy, 2^31 doubles would take on the order of
    10GB of memory. And even if you can host that many entries, computations
    will take forever. Thus, I am worried that some "basic solution" might not
    be good enough for you.


    Best

    Kai-Uwe Bux

    ps.: As for general advice on designing a matrix class, you might consider
    not using m[row][col] as the way to access coefficients. If you overload

    double & operator() ( size_type row, size_type col )

    and

    double const & operator() ( size_type row, size_type col ) const

    you have greater flexibility in designing the internals of your class (this
    can pay off for sparse matrix optimizations or special shape matrices). In
    this case, you would use

    m(row,col)

    to access coefficients.
    Kai-Uwe Bux, Sep 24, 2005
    #7
  8. LumisROB

    LumisROB Guest

    On Sat, 24 Sep 2005 10:38:58 -0400, Kai-Uwe Bux <>
    wrote:

    > I am asking since using some
    >simple-minded allocation strategy, 2^31 doubles would take on the order of
    >10GB of memory. And even if you can host that many entries, computations
    >will take forever. Thus, I am worried that some "basic solution" might not
    >be good enough for you.
    >


    The maximum dimension is a matrix of the type double m[10^5][10^5] to
    intend us
    Then 10^10 elements of double. Unfortunately the matrix has to be
    dense
    The most serious calculation that I have to do is a dot scalar product
    among two lines.However I have to make many non sequential accesses to
    the elements



    >ps.: As for general advice on designing a matrix class, you might consider
    >not using m[row][col] as the way to access coefficients. If you overload
    >
    > double & operator() ( size_type row, size_type col )
    >
    >and
    >
    > double const & operator() ( size_type row, size_type col ) const
    >
    >you have greater flexibility in designing the internals of your class (this
    >can pay off for sparse matrix optimizations or special shape matrices). In
    >this case, you would use
    >
    > m(row,col)
    >
    >to access coefficients.


    Very beautiful.... I like more always the c++ for me that arrival from
    the fortran..... unfortunately however the things are complicated for
    me (I am a beginner in the c++) and I have little time to resolve this
    problem... I would Be already happy to find a solution that allows me
    to reach the finishing line. I had tried to resolve with a vector
    <double> v without dimensions and despite it was a little efficient in
    comparison to vector <double> v(100000000) (total of elements 10^8
    --> ) it suited me if there had not been that accursed limitation -->

    vector <double> v(100000000) :
    time of creation 30 sec (this speed has surprised me and therefore I
    thought... perhaps naïvely, to build a vector <vector <double >> and
    to brightly resolve..but from what seems me to understand it is not an
    easy assignment it is not true?

    Heartful thanks

    ROB
    LumisROB, Sep 24, 2005
    #8
  9. LumisROB

    LumisROB Guest

    On Sat, 24 Sep 2005 21:27:23 +1000, "benben" <moc.liamtoh@hgnohneb
    read backward> wrote:


    >My approach would be:
    >
    > template <typename ElementT, typename AllocatorT>
    > class matrix
    > {
    > public:
    > typedef ElementT element_type;
    > typedef std::size_t size_type;
    >
    > private:
    > std::vector<element_type, AllocatorT> repr;
    > size_type num_rows;
    > size_type num_cols;
    >
    > public:
    > matrix(size_type r, size_type c);
    > size_type row_size(void);
    > size_type col_size(void);
    > element_type& operator() (size_type r, size_type c);
    > const element_type& operator()(size_type r, size_type c) const;
    >
    > // ... etc
    > };
    >



    Indeed sublime.... but if enter in such a forest.. I am sure that I go
    out consumes only from there after few months...... I arrive from the
    fortran and I am moving the first footsteps in the c++ and... I assure
    you that it is not so simple..

    Heartful Thanks to you and to parsenaama

    ROB
    LumisROB, Sep 24, 2005
    #9
  10. LumisROB

    Kai-Uwe Bux Guest

    LumisROB wrote:

    > On Sat, 24 Sep 2005 10:38:58 -0400, Kai-Uwe Bux <>
    > wrote:
    >
    >> I am asking since using some
    >>simple-minded allocation strategy, 2^31 doubles would take on the order of
    >>10GB of memory. And even if you can host that many entries, computations
    >>will take forever. Thus, I am worried that some "basic solution" might not
    >>be good enough for you.
    >>

    >
    > The maximum dimension is a matrix of the type double m[10^5][10^5] to
    > intend us
    > Then 10^10 elements of double. Unfortunately the matrix has to be
    > dense
    > The most serious calculation that I have to do is a dot scalar product
    > among two lines.However I have to make many non sequential accesses to
    > the elements


    Now that's a lot of entries. You might run into serious trouble here. There
    are different limitations that you might face. For one, allocation of a
    single block of that size is probably not supported. However, there might
    be an even worse problem: the total size of the heap might be insufficient.
    Also, if your compiler thinks that pointers are 32 bits, then there will be
    no way to address 10^10 points in memory since 2^32 < 10^10. May I ask,
    what platform will be running this code?


    As for dense matrix implementations, there is a simple minded strategy that
    avoids allocating rows*cols doubles in one big chunk:


    #include <memory>

    template < typename T >
    struct matrix {

    typedef typename std::size_t size_type;
    typedef T value_type;

    private:

    size_type rows;
    size_type cols;
    typedef T* RowVector;
    RowVector* data;

    public:

    matrix ( size_type r, size_type c, value_type t = value_type() )
    : rows ( r )
    , cols ( c )
    , data ( new RowVector [ this->rows ] )
    {
    size_type rows_constructed = 0;
    try {
    while ( rows_constructed < rows ) {
    this->data[ rows_constructed ] = new value_type [ this->cols ];
    for ( size_type j = 0; j < this->cols; ++ j ) {
    this->data[rows_constructed][j] = t;
    }
    ++ rows_constructed;
    }
    }
    catch ( ... ) {
    while ( rows_constructed > 0 ) {
    -- rows_constructed;
    delete [] this->data[ rows_constructed ];
    }
    delete [] this->data;
    throw;
    }
    }

    ~matrix ( void ) {
    for ( size_type i = 0; i < rows; ++ i ) {
    delete [] this->data;
    }
    delete [] this->data;
    }

    size_type row_size ( void ) const {
    return ( this->rows );
    }

    size_type col_size ( void ) const {
    return ( this->cols );
    }

    T & operator() ( size_type r, size_type c ) {
    return( this->data[r][c] );
    }

    T const & operator() ( size_type r, size_type c ) const {
    return( this->data[r][c] );
    }

    }; // class matrix<T>


    This is untested code and I left out the copy constructor, and the
    assignment operator. The price for allocating several blocks is a more
    complicated constructor since cleaning up is more difficult. Also, you are
    using a little more memory. Note that using vectors will incur additional
    overhead as every vector stores its size.


    Another idea would be to view a big matrix as a block matrix. But I am not
    sure if that would help to circumvent the limitations that you are running
    into.



    Best

    Kai-Uwe Bux
    Kai-Uwe Bux, Sep 24, 2005
    #10
  11. LumisROB

    LumisROB Guest

    On Sat, 24 Sep 2005 12:54:23 -0400, Kai-Uwe Bux <>
    wrote:

    >
    >Now that's a lot of entries. You might run into serious trouble here. There
    >are different limitations that you might face. For one, allocation of a
    >single block of that size is probably not supported.


    But then because this whole publicity around 64 bit?
    Mathematica 5.2 say to be to 64bit and I have verified instead that it
    has the 2^32 limitation
    The same thing has happened me with Matlab



    >. May I ask,
    >what platform will be running this code?




    Some people have recommended that the only street is Linux Suse 9.3
    (64) + gcc 3.3.3
    I have tried with Visual c++Net 8 and WinXP(64) but I have had
    problems in the management of the memory of swap (everything well
    actually to when the dimension of the busy memory reentered in the
    dimension of the ram but as soon as it overflowed the block happened)

    >
    >
    >As for dense matrix implementations, there is a simple minded strategy that
    >avoids allocating rows*cols doubles in one big chunk:
    >
    >
    >#include <memory>
    >
    >template < typename T >
    >struct matrix {


    to resolve this problem is more complicated than objectively I
    thought. The code that you have written me I am sure it will serve me
    to think of us a little.
    I retire me and I try to see if I succeed in understanding to fund of
    it the inspiring philosophy.Unfortunately I have available little time
    I am busy in other things. Among a few weeks if I didn't have to
    succeed I will try again to ask help. Unbelievable your preparation
    on the c++!!!
    For now I thank you, I make some tests and I see if I succeed in
    drawing something of profit.
    I infinitely thank you for your time
    Good-bye or better hearing again us

    Rob
    "At times the generosity of the human mind doesn't stop never
    marveling us"
    LumisROB, Sep 24, 2005
    #11
  12. LumisROB

    persenaama Guest

    A case study, let's say overhead per std::vector object is N, and
    overhead for allocator to allocate a contiguous block of memory is M.

    If we have a vector of vector's (case A) and only single vector to hold
    the whole matrix (case B) the memory overhead would look something like
    this (for W times H matrix)

    case A:
    (H + 1) * (N+M)

    case B:
    N + M

    On a real-world system, Microsoft (R) 32-bit C/C++ Optimizing Compiler
    Version 13.10.3077 for 80x86 using Dinkumware std implementation that
    ships with that version of the compiler, compiling for 32-bit IA32
    using double as the datatype to store in each matrix "cell", the
    constants N and M would look like this:

    N == sizeof(std::vector<double>) == 16
    M == 24
    (therefore N+M is 40)
    sizeof(double) == 8

    For 1x1 matrix the overhead would be 80, where the data stored itself
    would take 1*1*8, so the overhead is 80/88*100 (=~ 91 %) of the userful
    "payload"

    For 10x10 the overhead is 35 %, 1000 x 1000 the overhead is 0.5 %

    In this light it might not be useful to try to optimize the storage
    with very big matrices, the returns seem neglible in these ranges.
    Though, using a single allocation block and accessing it with stride to
    next row is trivial and there is no practical reason not to do that..
    persenaama, Sep 26, 2005
    #12
  13. LumisROB

    LumisROB Guest

    On 26 Sep 2005 08:54:40 -0700, "persenaama" <>
    wrote:

    Hi Parsenaama

    >In this light it might not be useful to try to optimize the storage
    >with very big matrices, the returns seem neglible in these ranges.
    >Though, using a single allocation block and accessing it with stride to
    >next row is trivial and there is no practical reason not to do that..


    ok if there was not the problem that for other reasons... I have to
    maintain the structure of matrix 2 x 2
    unfortunately!!!!

    Heartfull thanks
    ROB
    LumisROB, Sep 27, 2005
    #13
  14. LumisROB

    persenaama Guest

    It's probably just me, but I didn't quite get that.. you meant that you
    make up the larger matrices from 2x2 ones? If that is the case, it is
    not a surmountable problem to have nesting when computing the offset in
    memory for a cell:

    OK, 2x2 sub-blocks.. this means that you will have 4 cells per
    sub-block, therefore the formula for addressing indivisual cell wold be
    something like this:

    struct block
    {
    int xsize; // matrix width
    int ysize; // matrix height

    int computeOffset(int x, int y)
    {
    const int blocksize = 2;

    int xblock = x / blocksize;
    int yblock = y / blocksize;
    x %= blocksize;
    y %= blocksize;

    // ... at this point (xblock,yblock) is which block..
    // ... (x,y) is location within the block

    // TODO: this could be made simpler when some assumptions I didn't
    // make could be verified.. so as it is..
    int offset = (yblock * (xsize/blocksize) + xblock) * blocksize *
    blocksize;
    offset += y * blocksize + x; // adjust for intra block position

    return offset;
    }
    };

    I could be way off mark but that's the basic idea I'd use for something
    like that, implementation details withstanding (disclaimer: I might not
    implement it like that but I apparently would demonstrate the basic
    idea like that :)

    Asserting, range-checking etc. is left as exercise to the reader (maybe
    just clip the (x,y), whatever)... also using "int" might not be
    recommended but again, I just wanted SOME type to demonstrate the
    concept.. I'm used to doing this with power-of-two data mostly (useful
    technique for storing spatially local data in memory close together, v.
    good for cache easily worth the more complex addressing -- which infact
    is cheap when using powers-of-two..) but that might be something
    completely different...
    persenaama, Sep 27, 2005
    #14
  15. LumisROB

    LunisRob Guest

    On 26 Sep 2005 22:57:04 -0700, "persenaama" <>
    wrote:


    ok heartfull thanks
    ROB
    LunisRob, Sep 27, 2005
    #15
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Sydex
    Replies:
    12
    Views:
    6,445
    Victor Bazarov
    Feb 17, 2005
  2. Ingo Nolden
    Replies:
    15
    Views:
    1,511
    Jerry Coffin
    Apr 30, 2005
  3. Xah Lee

    [perl-python] sorting matrixes

    Xah Lee, Mar 22, 2005, in forum: Python
    Replies:
    2
    Views:
    373
    Xah Lee
    Mar 28, 2005
  4. Jose Garcia

    MATRIXES - Dinamic Memory

    Jose Garcia, Feb 10, 2005, in forum: C Programming
    Replies:
    3
    Views:
    350
    Barry Schwarz
    Feb 11, 2005
  5. KinGPIN
    Replies:
    1
    Views:
    302
    mlimber
    Jul 24, 2006
Loading...

Share This Page