Announcement

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

  • Mata Program which chooses every odd element of a vector (row or column)

    Hello,

    I would like to write a mata function, which chooses every other/second row respectively column of a vector and calculates the sum of these values.
    Code:
    function test (real vector x){
    real scalar i
    real scalar j
    real scalar r                
    real scalar c
    
    r = rows(x)
    c = cols(x)
    
    if (c==1) {
    if (mod(i,2):==0){
    B=x[i ,1]
    sum(B)
    }
    }
    if (r==1) {
    if(mod(j,2):==0) {
    A=x[1,j]
    sum(A)
    }
    }
    }
    I tried to select every other column/row with the command mod(), but this does not work. I am not sure how to tell the program that it must only allow for every other column/row.

    Thank you for your help in advance.

  • #2
    I'm not entirely sure I follow...

    Do you want every second row *and* column? And then sum the result?
    In other words, sum every element where column and row indexes are even?

    And do you want a scalar result, or some sort of matrix?

    Comment


    • #3
      I would not bother writing a function for this purpose. Just code

      Code:
      sum(x :* !mod(x, 2))
      Best
      Daniel

      Comment


      • #4
        Try:

        Code:
        function oddsum(real colvector x) return(colsum(select(x, mod(1::rows(x),2))))
        function evensum(real colvector x) return(colsum(select(x, !mod(1::rows(x),2))))
        A test of the code:
        Code:
        : x=1::6
        : oddsum(x)
          9
        : evensum(x)
          12
        Kind regards

        nhb

        Comment


        • #5
          Daniel's solution sums over the elements of x which are even, not on the elements positionned on the even indices of the rows (or columns if it is a rowvector).
          Alexander Gerner The problem in your function is that you are refering to i to select the rows which index is even, but i is not defined in the function. Use the select function to make such a selection. An alternative way to Niels' solution is to select the indices and use subscripting.


          Code:
          clear mata
          mata:
          real scalar test (real vector x)
          {
          
                  if (rows(x)==1) {
                          real rowvector colIndex
                          colIndex = 1..cols(x)
                          return (sum(x[,select(colIndex,!mod(colIndex,2))]))
                  }
                  else if (cols(x)==1) {
                          real rowvector rowIndex
                          rowIndex = 1..rows(x)
                          return (sum(x[select(rowIndex,!mod(rowIndex,2)),]))
                  }
                  // else _error(3200,"input not a vector") -> not strictly necessary since we have defined x as a vector
          }
              
          a = 1..5
          b = 1::5
          a
          b
          test(a)
          test(b)
          
              
          end

          Code:
          : a = 1..5
          
          : b = 1::5
          
          : a
                 1   2   3   4   5
              +---------------------+
            1 |  1   2   3   4   5  |
              +---------------------+
          
          : b
                 1
              +-----+
            1 |  1  |
            2 |  2  |
            3 |  3  |
            4 |  4  |
            5 |  5  |
              +-----+
          
          : test(a)
            6
          
          : test(b)
            6

          Comment


          • #6
            Originally posted by Christophe Kolodziejczyk View Post
            Daniel's solution sums over the elements of x which are even, not on the elements positionned on the even indices of the rows (or columns if it is a rowvector).
            Very good catch, thanks. Indeed, it should be

            Code:
            !mod((1..length(x)), 2) * vec(x)
            Best
            Daniel

            Comment


            • #7
              daniel klein Elegant solution...and no need to write a function, unless one has a hard time to remember

              Comment


              • #8
                Thank you all or your help, it worked out perfectly. But may you tell me what ":*" does in the command mod() mean?

                Comment


                • #9
                  Note that the expression in #3 returns the sum of the odd values not of the odd indices of a vector, as has been pointed out by Christophe. So you want to use the expression in #6 instead.

                  Anyway, you can read up on the colon operator, typing

                  Code:
                  help m2_op_colon
                  Best
                  Daniel

                  Comment

                  Working...
                  X