Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Most implementations I know use a 1D array with wrappers either via MACROS or methods to access the 2D data. I myself can't say which is faster and I can hardly see a case where this would really matter.</p> <p>However this being said I would still recommend using 1D arrays for the following reasons:</p> <ol> <li>easier to allocate and release dynamically (If you want to allocate your data dynamically and maintain the matrix[i][j] pattern then you are allocating an array of arrays - slower to allocate more bug prone, you have to release each array separately)</li> <li>if you allocate dynamically and have to copy the data to a 3d party library say OpenGL or OpenCV you are into some trouble since they need the data to be contiguous.</li> <li>It will be easier to store and read the matrix from files or other persistent storage.</li> <li>even if you don't allocate dynamically you will have to do all sorts of ugly castings to handle the transfer of memory to 3d party libraries.</li> <li>it's super easy to create a structure with methods to have efficient 2d access to your data without multiplications or unclear indexing. Or for that matter use MACROS to encapsulate the ugly multiplications for you.</li> <li>You could even create a structure to look like the next sample and maintain the same benefits of a 1d array with the readability of a 2d array:</li> </ol> <pre><code> template&lt;typename T&gt; struct Matrix4x4 { struct index { int row, col; index(int r = 0, int c = 0) : row(r), col(c){} index(index const & cp) : row(cp.row), col(cp.col) { } //Assignment ommited for brevity }; /* Constructors, Assignments etc. ommited for brevity */ T m00, m01, m02, m03; T m10, m11, m12, m13; T m20, m21, m22, m23; T m30, m31, m32, m33; T * toArray() const { return &m00; } T * toArray() { return &m00; } T * row(int r) { return (&m00) + r*4; } T * row(int r) const { return (&m00) + r*4; } T & operator()(int r, int c) { return *row(r)[c]; } T const & operator()(int r, int c) const { return *row(r)[c]; } T & operator[](index const & idx) { return row(idx.row)[idx.col]; } T const & operator[](index const & idx) const { return row(idx.row)[idx.col]; } }; </code></pre> <p>In your code you can do:</p> <pre><code>typedef Matrix4x4&lt;double&gt; Matrix4x4d; Matrix4x4d mat; /* You can do any of the following */ mat.m23 = 6.0; mat(2,3) = 6.0; mat[Matrix4x4d::index(2,3)] = 6.0; mat.row(2)[3] = 6.0; mat.toArray()[2*4 + 3] = 6.0; #define M(m,r,c) (*((&amp;m.m00) + r*4 + c)) M(mat,2,3) = 6.0; </code></pre> <p>I myself implemented several matrix libraries over the years and always opted for the 1d solution.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload