Announcement

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

  • Building symmetry index of a Matrix

    Dear Mata users,
    I have a square Matrix Q let's say :
    Code:
    mata : Q=runiform(3,3)
    I'd like to obtain the scalar given by the formula (fagiolo, 2006; fagiolo et al, 2010 (p.28)):
    Click image for larger version

Name:	sq.png
Views:	1
Size:	3.8 KB
ID:	1346601



    where qij are the elements of Q, and 0<qij<1 (as given by runiform(), except that the diagonal elements are all set to one.).

    Later I should get:
    Click image for larger version

Name:	s.png
Views:	1
Size:	2.5 KB
ID:	1346602

    This second step is easier, the result is supposed to be bounded between 0 and 1 and measure the degree of symmetry of the initial matrix Q.

    Any thoughts for the first step?
    thanks,
    Charlie

  • #2
    I think this does what you need, but please check some example by hand.
    Code:
    mata:
    N = 3  // for example
    Q = runiform(3,3)  // for example
    // Put 1s on the diagonal.  I can't remember the "nice" way to do this.
    Q = (Q - diag(Q)) + diag(J(rows(Q), rows(Q), 1))
    //
    // The next 4 lines could be one line, but I broke them up for clarity.
    num  = sum(Q :* (Q'))  
    den = sum(Q :* Q)
    TildeSQ = 1 - num/den
    SQ = STildeQ * (N + 1)/(N-1)
    //
    // Echo the key pieces for hand-checking.
    Q; TildeSQ;
    end

    Comment


    • #3
      Mike was quicker, I hope mine is a little "nicer"

      Code:
      mata :
      
      /*
          function symindx() */
      
      real scalar symindx(real matrix Q, | real scalar std)
      {
          real scalar s
          
          if (rows(Q) != cols(Q)) {
              _error(3205)
          }
          
          if (any(diagonal(Q) :!= 1)) {
              _error(3300)
          }
          
          if (hasmissing(Q)) {
              return(.)
          }
          
          if (issymmetric(Q)) {
              return(0)
          }
          
          s = 1 - quadsum(Q':*Q)/quadsum(diagonal(Q'Q))
          if (std) {
              s = (rows(Q) + 1)/(rows(Q) - 1) * s
          }
          
          return(s)
      }
      
      /*
          examples */
          
      Q = runiform(3, 3)
      
      // replace diagonal with 1
      _diag(Q, 1)
      
      symindx(Q)
      
      // unstandardized version
      symindx(Q, 0)
      
      // now a symmetric matrix
      Q = Q'Q
      _diag(Q, 1)
      
      symindx(Q)
      
      // asymmetric matrix
      Q = (1, 1, 1, 1)\ (0, 1, 1, 1)\ (0, 0, 1, 1)\ (0, 0, 0, 1)
      
      symindx(Q)
      
      end
      Best
      Daniel

      Comment


      • #4
        Definitely nicer than my hack!

        Comment


        • #5
          Both are impressive and appreciable answers!
          Thanks Daniel nonetheless, the function built really fits my needs

          Best,
          Charlie

          Comment

          Working...
          X