Announcement

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

  • Changing elements in associative arrays

    Dear Stata users,
    I have a question on associative arrays in mata.

    Let’s assume I have an array called dX composed of 4 matrices X1, X2, X3 and X4 (each of dimensions nxn). Let’s call these the layers of the array. If I want to change element (i,j) in layer k by value z, I would do the following

    1. W=asarray(dX,k)
    2. W[i,j]=z
    3.asarray(dX,k,W)

    In step 1 I would obviously recover matrix Xk for the first iteration but after a first round of changes it will not be matrix Xk anymore.
    in step 2 I change the element of interest with the wanted value
    in step 3 I replace layer k with my new matrix W

    I know that we can access element (i,j) of layer k in array dX by typing “asarray(dX,k)[1,1]”. Unfortunately typing “asarray(dX,k)[1,1]=z” would not work.

    I am pretty sure that my way of proceeding is not efficient, but I did not find any better way up to now.

    Any help would be appreciated

    All the best

    Vincenzo

  • #2
    My understanding of asarray() is the same as yours. Your associative array elements are matrices, and so the arrays need to be replaced in their entirety, there is no provision for replacing a single element, or a slice, or anything less than the entire matrix.

    Comment


    • #3
      Dear Wiliam, thank you for your comment. I will have to live with it then.

      Comment


      • #4
        You can approach what you want by using pointers.
        Code:
        version 15.1
        
        clear *
        
        mata:
        
        // Set up
        M = J(2, 2, 0)
        p = &M
        
        A = asarray_create("string", 1, 5, 0.5, 1.5)
        
        asarray(A, "M", p)
        
        
        // Here, change the element of the matrix in situ
        q = asarray(A, "M")
        
        (*q)[2, 2] = 1
        // No replacement of the layer in the associative array at all
        
        
        // Test
        *(asarray(A, "M"))
        
        end
        
        exit
        You can probably also do the same using a static member variable of an object to hold the matrix in lieu of a pointer.

        In lieu of either, though, I would probably just write a function (or class method) to take care of things behind the scenes in a more straightforward manner.

        Comment


        • #5
          Dear Joseph, I see. I will try this solution. Thank you!

          Comment


          • #6
            If you do, then the direct analogue of your “asarray(dX,k)[1,1]=z” is
            Code:
            (*(asarray(A, "M"))[2, 2]) = 1
            So, you can shorten the assignment to a single line of code, as in the following modification of the code in #4 above.

            .ÿ
            .ÿversionÿ15.1

            .ÿ
            .ÿclearÿ*

            .ÿ
            .ÿlocalÿline_sizeÿ`c(linesize)'

            .ÿsetÿlinesizeÿ72

            .ÿ
            .ÿmata:
            -------------------------------------------------ÿmataÿ(typeÿendÿtoÿexit
            >ÿ)ÿ--------------------------------------------------------------------
            :ÿ
            :ÿ//ÿSetÿup
            :ÿMÿ=ÿJ(2,ÿ2,ÿ0)

            :ÿpÿ=ÿ&M

            :ÿ
            :ÿAÿ=ÿasarray_create("string",ÿ1,ÿ5,ÿ0.5,ÿ1.5)

            :ÿ
            :ÿasarray(A,ÿ"M",ÿp)

            :ÿ
            :ÿ
            :ÿ//ÿHere,ÿchangeÿtheÿelementÿofÿtheÿmatrixÿinÿsitu
            :ÿ(*(asarray(A,ÿ"M"))[2,ÿ2])ÿ=ÿ1

            :ÿ
            :ÿ
            :ÿ//ÿTest
            :ÿ*(asarray(A,ÿ"M"))
            [symmetric]
            ÿÿÿÿÿÿÿ1ÿÿÿ2
            ÿÿÿÿ+---------+
            ÿÿ1ÿ|ÿÿ0ÿÿÿÿÿÿ|
            ÿÿ2ÿ|ÿÿ0ÿÿÿ1ÿÿ|
            ÿÿÿÿ+---------+

            :ÿ
            :ÿend
            ------------------------------------------------------------------------

            .ÿ
            .ÿsetÿlinesizeÿ`line_size'

            .ÿ
            .ÿexit

            endÿofÿdo-file


            .


            Again, I find all of this too clever by half, and would favor a more straightforward approach (read: readily understood six months from now) that is wrapped in a dedicated function.

            Comment


            • #7
              I am relatively new to the use of pointers in Mata and have thusfar been impressed with their utility.

              Specific to this query, I have been curious about using pointers in conjunction with mata matsave. Specifically, if I define a pointer matrix and save it using mata matsave it appears from a few instances I've tried that the contexts of the "pointee" matrixes are saved as well (i.e. are restored even after clear or starting a new session).

              I wasn't able to find anything specific in the documentation speaking to this, but is my novice's observation accurate, i.e. that mata matsave of pointer matrixes will result in the contents being saved and, as such, restorable with mata matuse even after the original "pointee" matrixes have been cleared?

              Thanks for any insights and/or references.

              Comment


              • #8
                Dear Joseph,
                your solution indeed works. I was wondering, do you think this would make my loop faster to run than my original solution?

                Sorry, I am not sure to get what you mean by dedicated function

                Thanks again a lot for all your help

                Best

                Vincenzo

                Comment

                Working...
                X