Announcement

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

  • MATA-looping through matrices & store strings in stata

    Hi, I'm new to mata and I have two problems related to MATA. Can someone please help me to find solutions to these.

    (1) Looping through matrices in MATA

    Code:
    mata
    
    for (j=1;j<=3;j++)
        {
            X=(1,2\3,5)
            m_1=(1,1\1,1)
            m_2=(2,3\5,6)
            m_3=(5,3\8,9)
            X-m_j // here I need to refer to the jth matrix at each iteration. i.e. when j=1 m_ j should equal to m_1 and so on..
    
        }
    
    end
    The output will be

    When j=1
    1 2
    +---------+
    1 | 0 1 |
    2 | 2 4 |
    +---------+

    When j=2
    1 2
    +-----------+
    1 | -1 -1 |
    2 | -2 -1 |
    +-----------+

    When j=3
    1 2
    +-----------+
    1 | -4 -1 |
    2 | -5 -4 |
    +-----------+

    (2) saving MATA string vector as variables of STATA

    Code:
    STATA code
    gen a1=1
    gen a2=1
    This creates two variables named a1 and a2 in stata

    I have a string vector in MATA. I need to do the same thing using MATA. (i.e. store the string names as variables)

    Code:
    mata
    mat1="a1","a2"
    // here I need the equivalent MATA code to generate the a1 and a2 variables
    end
    Thank you for your time


  • #2
    Here is one way each to accomplish of your objectives.

    .ÿversionÿ14.1

    .ÿ
    .ÿclearÿ*

    .ÿsetÿmoreÿoff

    .ÿquietlyÿsetÿobsÿ2

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

    .ÿsetÿlinesizeÿ78

    .ÿ
    .ÿmata:
    -------------------------------------------------ÿmataÿ(typeÿendÿtoÿexit)ÿ----
    :ÿmataÿclear

    :ÿmataÿsetÿmatastrictÿon

    :ÿ
    :ÿvoidÿfunctionÿpraveen1()ÿ{
    >ÿ
    >ÿÿÿÿÿÿÿÿÿrealÿmatrixÿX
    >ÿÿÿÿÿÿÿÿÿXÿ=ÿ(1,ÿ2ÿ\ÿ3,ÿ5)
    >ÿ
    >ÿÿÿÿÿÿÿÿÿpointer(realÿmatrix)ÿvectorÿMatrices
    >ÿ
    >ÿÿÿÿÿÿÿÿÿMatricesÿ=ÿ&(1,ÿ1ÿ\ÿ1,ÿ1)
    >ÿÿÿÿÿMatricesÿ=ÿ(Matrices,ÿ&(2,ÿ3ÿ\ÿ5,ÿ6))
    >ÿÿÿÿÿMatricesÿ=ÿ(Matrices,ÿ&(5,ÿ3ÿ\ÿ8,ÿ9))
    >ÿ
    >ÿÿÿÿÿÿÿÿÿrealÿscalarÿj
    >ÿÿÿÿÿÿÿÿÿforÿ(j=1;ÿj<=3;ÿj++)ÿ{
    >ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿprintf("\n\nWhenÿjÿ=ÿ%1.0f\n",ÿj)
    >ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿXÿ-ÿ*Matrices[j]
    >ÿÿÿÿÿÿÿÿÿ}
    >ÿ}

    :ÿ
    :ÿpraveen1()


    Whenÿjÿ=ÿ1
    ÿÿÿÿÿÿÿ1ÿÿÿ2
    ÿÿÿÿ+---------+
    ÿÿ1ÿ|ÿÿ0ÿÿÿ1ÿÿ|
    ÿÿ2ÿ|ÿÿ2ÿÿÿ4ÿÿ|
    ÿÿÿÿ+---------+


    Whenÿjÿ=ÿ2
    ÿÿÿÿÿÿÿÿ1ÿÿÿÿ2
    ÿÿÿÿ+-----------+
    ÿÿ1ÿ|ÿÿ-1ÿÿÿ-1ÿÿ|
    ÿÿ2ÿ|ÿÿ-2ÿÿÿ-1ÿÿ|
    ÿÿÿÿ+-----------+


    Whenÿjÿ=ÿ3
    ÿÿÿÿÿÿÿÿ1ÿÿÿÿ2
    ÿÿÿÿ+-----------+
    ÿÿ1ÿ|ÿÿ-4ÿÿÿ-1ÿÿ|
    ÿÿ2ÿ|ÿÿ-5ÿÿÿ-4ÿÿ|
    ÿÿÿÿ+-----------+

    :ÿ
    :ÿvoidÿfunctionÿpraveen2()ÿ{
    >ÿ
    >ÿÿÿÿÿÿÿÿÿstringÿvectorÿNewvarlist
    >ÿÿÿÿÿÿÿÿÿNewvarlistÿ=ÿ("a1",ÿ"a2")
    >ÿ
    >ÿÿÿÿÿÿÿÿÿrealÿrowvectorÿNewvarindices
    >ÿÿÿÿÿÿÿÿÿNewvarindicesÿ=ÿst_addvar("byte",ÿNewvarlist)
    >ÿ
    >ÿÿÿÿÿÿÿÿÿrealÿmatrixÿNewData
    >ÿÿÿÿÿÿÿÿÿNewDataÿ=ÿJ(st_nobs(),ÿlength(Newvarlist),ÿ1)
    >ÿ
    >ÿÿÿÿÿÿÿÿÿst_store(.,ÿNewvarindices,ÿNewData)
    >ÿ
    >ÿÿÿÿÿÿÿÿÿstata("list,ÿnoobs")
    >ÿ}

    :ÿ
    :ÿpraveen2()

    ÿÿ+---------+
    ÿÿ|ÿa1ÿÿÿa2ÿ|
    ÿÿ|---------|
    ÿÿ|ÿÿ1ÿÿÿÿ1ÿ|
    ÿÿ|ÿÿ1ÿÿÿÿ1ÿ|
    ÿÿ+---------+

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

    .ÿ
    .ÿsetÿlinesizeÿ`linesize'

    .ÿ
    .ÿexit

    endÿofÿdo-file


    .

    Comment


    • #3
      Thank you very much Joseph. That solved my problem.

      Comment


      • #4
        Just a quick question. Is there a easy way to achieve this than using pointers?
        For example: in stata same code can be written

        Code:
        forval j = 1/3 {
            matrix X=(1,2\3,5)
            matrix m_1=(1,1\1,1)
            matrix m_2=(2,3\5,6)
            matrix m_3=(5,3\8,9)
            matrix A=X-m_`j'
            matrix list A
        }
        STATA uses ` ' to refer to the jth matrix. Thank you very much for your assistance.

        Comment


        • #5
          If the matrices are all the same dimension, you could combine the matrices and then refer to the correct columns of the matrix instead of using multiple matrices. If they are not of the same dimension, I think that's still possible, but you would have to create two vectors first which indicate the relevant first and last column. You'd then loop over these vectors to get the right column numbers in each iteration.

          There's probably a more elegant solution, but that's all I can come up with.

          Comment


          • #6
            Originally posted by praveen wp View Post
            Just a quick question. Is there a easy way to achieve this than using pointers?
            For example: in stata same code can be written

            Code:
            forval j = 1/3 {
            matrix X=(1,2\3,5)
            matrix m_1=(1,1\1,1)
            matrix m_2=(2,3\5,6)
            matrix m_3=(5,3\8,9)
            matrix A=X-m_`j'
            matrix list A
            }
            STATA uses ` ' to refer to the jth matrix. Thank you very much for your assistance.
            You can achieve this without explicit use of pointers, for example, you can use an associative array (which would be using pointers behind the scenes). See below.

            But nothing that I've seen in the documentation suggests that Mata has macro features that Stata has.

            By the way, you're redefining the same matrices in each pass through the loop. Wouldn't it be better to assign the matrices just once before entering the loop?


            .ÿversionÿ14.1

            .ÿ
            .ÿclearÿ*

            .ÿsetÿmoreÿoff

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

            .ÿsetÿlinesizeÿ78

            .ÿ
            .ÿmata:
            -------------------------------------------------ÿmataÿ(typeÿendÿtoÿexit)ÿ----
            :ÿmataÿsetÿmatastrictÿon

            :ÿ
            :ÿvoidÿfunctionÿpraveen1a()ÿ{
            >ÿ
            >ÿÿÿÿÿÿÿÿÿrealÿmatrixÿX
            >ÿÿÿÿÿÿÿÿÿXÿ=ÿ(1,ÿ2ÿ\ÿ3,ÿ5)
            >ÿ
            >ÿÿÿÿÿÿÿÿÿclassÿAssociativeArrayÿscalarÿa
            >ÿÿÿÿÿÿÿÿÿa.reinit("real")
            >ÿ
            >ÿÿÿÿÿÿÿÿÿa.put(1,ÿ(1,ÿ1ÿ\ÿ1,ÿ1)ÿ)
            >ÿÿÿÿÿÿÿÿÿa.put(2,ÿ(2,ÿ3ÿ\ÿ5,ÿ6)ÿ)
            >ÿÿÿÿÿÿÿÿÿa.put(3,ÿ(5,ÿ3ÿ\ÿ8,ÿ9)ÿ)
            >ÿÿÿÿÿÿÿÿÿa.notfound(ÿJ(2,ÿ2,ÿ.)ÿ)
            >ÿ
            >ÿÿÿÿÿÿÿÿÿrealÿscalarÿj
            >ÿÿÿÿÿÿÿÿÿforÿ(j=1;ÿj<=3;ÿj++)ÿ{
            >ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿprintf("\n\nWhenÿjÿ=ÿ%1.0f\n",ÿj)
            >ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿXÿ-ÿa.get(j)
            >ÿÿÿÿÿÿÿÿÿ}
            >ÿ}

            :ÿ
            :ÿpraveen1a()


            Whenÿjÿ=ÿ1
            ÿÿÿÿÿÿÿ1ÿÿÿ2
            ÿÿÿÿ+---------+
            ÿÿ1ÿ|ÿÿ0ÿÿÿ1ÿÿ|
            ÿÿ2ÿ|ÿÿ2ÿÿÿ4ÿÿ|
            ÿÿÿÿ+---------+


            Whenÿjÿ=ÿ2
            ÿÿÿÿÿÿÿÿ1ÿÿÿÿ2
            ÿÿÿÿ+-----------+
            ÿÿ1ÿ|ÿÿ-1ÿÿÿ-1ÿÿ|
            ÿÿ2ÿ|ÿÿ-2ÿÿÿ-1ÿÿ|
            ÿÿÿÿ+-----------+


            Whenÿjÿ=ÿ3
            ÿÿÿÿÿÿÿÿ1ÿÿÿÿ2
            ÿÿÿÿ+-----------+
            ÿÿ1ÿ|ÿÿ-4ÿÿÿ-1ÿÿ|
            ÿÿ2ÿ|ÿÿ-5ÿÿÿ-4ÿÿ|
            ÿÿÿÿ+-----------+

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

            .ÿ
            .ÿsetÿlinesizeÿ`linesize'

            .ÿ
            .ÿexit

            endÿofÿdo-file


            .

            Comment


            • #7
              Thank you very much Jesse and Joseph. You have been really helpful..

              Comment


              • #8
                The "use" of Stata Macros in Mata is explained in this Stata Journal article. In Mata Macros can't be used in the same way as in Stata, i.e for looping. Use pointers (or associative arrays as usggested by Joseph) to collect objects of different types or shapes. I think in this case pointers should be easy enough. For more complicated cases associative arrays would be a nice solution.


                Comment

                Working...
                X