Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Pointer matrixes and objects to which they point

    I'm still a novice when it comes to using pointer matrixes, but I'm finding them increasingly useful in Mata programming exercises. This posting is not so much a query but rather an alert—prompted by programming errors I've made—to others who may also be relatively new to using pointer matrixes.

    The basic message can be conveyed by a simple example. Consider this code:
    Code:
    mata
    
    pmat1=pmat2=J(2,1,NULL)
    A=(1,2)\(3,4)
    for (j=1;j<=2;j++) {
     A=j:*A
     pmat1[j]=&A
     pmat2[j]=&(A:+0)
    }
    *pmat1[1]
    *pmat1[2]
    *pmat2[1]
    *pmat2[2]
    
    pmat1
    pmat2
    
    end
    which results in
    Code:
    : *pmat1[1]
           1   2
        +---------+
      1 |  2   4  |
      2 |  6   8  |
        +---------+
    
    : *pmat1[2]
           1   2
        +---------+
      1 |  2   4  |
      2 |  6   8  |
        +---------+
    
    : *pmat2[1]
           1   2
        +---------+
      1 |  1   2  |
      2 |  3   4  |
        +---------+
    
    : *pmat2[2]
           1   2
        +---------+
      1 |  2   4  |
      2 |  6   8  |
        +---------+
    
    :
    : pmat1
                        1
        +------------------+
      1 |  0x7f8c07804aa8  |
      2 |  0x7f8c07804aa8  |
        +------------------+
    
    : pmat2
                        1
        +------------------+
      1 |  0x7f8c199b9d78  |
      2 |  0x7f8c0945be08  |
        +------------------+
    The reasoning is (I believe) straightforward: pointing to the matrix A is not the same thing as pointing to the (unnamed) matrix A:+0.

    I suspect this behavior is well known to the pointer experts among you, but hopefully those new to pointers might learn from the errors I've made.

  • #2
    pmat1[1] and pmat1[2] both point to the same matrix A. After the loop, matrix A is (2,4)\(6,8).
    pmat2[1] points to an (unnamed) matrix created in the first step of the loop, pmat[2] points to another (unnamed) matrix created in the second step of the loop.

    What I find noteworthy - and I only discovered this a few days ago - is that &(A) is the same as &A, but performing an otherwise redundant computation such as adding zeros, &(A:+0), makes a difference.
    https://twitter.com/Kripfganz

    Comment


    • #3
      Thanks for this observation, Sebastian.

      I discovered this accidentally when (as in the simple example in #1) I was using a pointer matrix as an accumulator matrix inside a loop. As this has usually been my reason for using pointers, I've started using an alternative approach, like that seen here:
      Code:
      mata
      
      function idp(a) {
       transmorphic matrix b
       b=a
       return(b)
      }
      
      pmat1=pmat2=J(2,1,NULL)
      A=(1,2)\(3,4)
      for (j=1;j<=2;j++) {
       A=j:*A
       pmat1[j]=&A
       pmat2[j]=&idp(A)
      }
      *pmat1[1]
      *pmat1[2]
      *pmat2[1]
      *pmat2[2]
      
      pmat1
      pmat2
      
      end
      which yields the same results as in #1:
      Code:
      : *pmat1[1]
             1   2
          +---------+
        1 |  2   4  |
        2 |  6   8  |
          +---------+
      
      : *pmat1[2]
             1   2
          +---------+
        1 |  2   4  |
        2 |  6   8  |
          +---------+
      
      : *pmat2[1]
             1   2
          +---------+
        1 |  1   2  |
        2 |  3   4  |
          +---------+
      
      : *pmat2[2]
             1   2
          +---------+
        1 |  2   4  |
        2 |  6   8  |
          +---------+
      
      :
      : pmat1
                          1
          +------------------+
        1 |  0x7f8c07804aa8  |
        2 |  0x7f8c07804aa8  |
          +------------------+
      
      : pmat2
                          1
          +------------------+
        1 |  0x7f8c1f81d6c8  |
        2 |  0x7f8c199b9d78  |
          +------------------+
      I realize this is substituting a mechanical "fix" instead of thoughtful/careful programming, but for my purposes it seems to be satisfactory. I also realize I could use other approaches like associative arrays, but the simplicity of pointers is quite appealing.

      Comment


      • #4
        A followup: Regarding Sebastian's #2, one would be inclined to think that &A and &(A) should yield different results. Since A is an expression (yes?) then &(A) would refer to the evaluation of the expression (e.g. page 96 of Bill Gould's The Mata Book). But as Sebastian notes &A and &(A) yield the same result. Understanding this is far above my pay grade, but at a minimum this seems useful to know if one is inclined to use pointers in a manner like that suggested in #3.

        Comment

        Working...
        X