Announcement

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

  • transfer partial column values into diagonal matrix as submatrix in a matrix, repeatly for many times?

    I have a Stata data file where there are 42 countries and 35 industries. Each column shows one country's final use of products from all country-sectors. (see the attached image of the data structure).

    Click image for larger version

Name:	pic1.JPG
Views:	2
Size:	243.8 KB
ID:	1427954

    Click image for larger version

Name:	pic2.JPG
Views:	1
Size:	248.2 KB
ID:	1427953


    I need to create a (42x42) block matrix, say D, from the data, where each block is a (35x35) diagonal submatrix formed from one country's final use of another country's 35 sectors(including its own). The final result will be a (42x35)x(42x35) matrix.

    e.g. The first 35 row values in the first column are Australia's final use of the products from its own 35 sectors:

    [ AUSfinaluse(1,1) ]
    [.............................]
    [ AUSfinaluse(i,1) ]
    [.............................]
    [AUSfinaluse(35,1)]

    from which I want to form the first (35x35) submatrix or D(1,1) looking like this:

    [ AUSfinaluse(1,1) 0............. 0 ]
    [ ... .......................................... ]
    [ 0 ... 0 AUSfinaluse(i,1) 0.....0 ]
    [ ... .......................................... ]
    [ 0 ...........0 AUSfinaluse(35,1) ]

    The next 35 row values of the first column are Australia's final use of the products from Austria (AUT)'s 35 sectors, from which to create submatrix D(2,1), looking like this:

    [ AUSfinaluse(36,1) 0............. 0 ]
    [ ... .......................................... ]
    [ 0 ... 0 AUSfinaluse(i,1) 0.....0 ]
    [ ... .......................................... ]
    [ 0 ...........0 AUSfinaluse(70,1) ]

    I have to repeat this for Austrialia's final use (column AUSfinaluse) of the products from the rest of the 40 countries; and then, do the same thing column by column for all the 42 countries' final use (42 columns).

    Any suggestion for an efficient solution to this task would be much appreciated!
    Attached Files

  • #2
    jerry pan --

    You could port things into mata and then just use the diagonal function to put values on the diagonal, i. e. something like:

    Code:
    /* generate some fictional data */
    set obs 90
    gen x = runiform()
    gen country = ""
    replace country = "AUS" in 1/45
    replace country = "USA" in 46/90
    gen ausdum = country == "AUS"
    gen usadum = country == "USA"
    
    /* get data into mata, diagonal matrix */
    mata:
    st_view(X=.,.,"x", "ausdum")
    Mat = diag(X)
    st_view(X=.,.,"x", "usadum")
    Mat = blockdiag(Mat,diag(X))
    You could apply this basic idea recursively and populate your matrix that way. However, it seems like you are making an enormous diagonal matrix which might be hard to work with. Is there a reason you can't just use a vector to hold the diagonals of all these matrices?

    Hope that helps!

    Matthew J. Baker

    Comment


    • #3
      Matthew J. Baker ,

      Thank you so much for the tip! It is very close to what I want. The final matrix, say M, I want to create is not a big diagonal, but its submatrices are diagonals. That's why I can't use a vector. Your tip is very helpful in forming these diagonal submatrices. I want to put each of these block diagonals in the final matrix M according to their position in the dataset, such that, e.g.(for two countries, Australia and USA):

      Block M[1,1] is:

      [ AUSfinaluse(1,1) 0............. 0 ]
      [ ... .......................................... ]
      [ 0 ... 0 AUSfinaluse(i,1) 0.....0 ]
      [ ... .......................................... ]
      [ 0 ...........0 AUSfinaluse(35,1) ]

      Block M[2,1] is:

      [ AUSfinaluse(36,1) 0........... 0 ]
      [ ... .......................................... ]
      [ 0 ... 0 AUSfinaluse(i,1) 0.....0 ]
      [ ... .......................................... ]
      [ 0 ...........0 AUSfinaluse(70,1) ]

      Block M[1,2] is:

      [ USAfinaluse(1,2) 0............. 0 ]
      [ ... .......................................... ]
      [ 0 ... 0 USAfinaluse(i,2) 0.....0 ]
      [ ... .......................................... ]
      [ 0 ...........0 USAfinaluse(35,2) ]

      Block M[2,2] is:

      [ USAfinaluse(36,2) 0........... 0 ]
      [ ... .......................................... ]
      [ 0 ... 0 USAfinaluse(i,2) 0.....0 ]
      [ ... .......................................... ]
      [ 0 ...........0 USAfinaluse(70,2) ]

      Also, what will be the efficient way to loop over the dataset to repeat the same task? In your coding st_view(), instead of creating a country dummy code, can I use string country code ("AUS", "USA") directly as the select variable?

      Many thanks!



      Comment

      Working...
      X