I've written an .ado file to randomly generate a correlation matrix, in order to draw correlated vectors using drawnorm. (I looked for existing code doing this, but couldn't find anything.) I realize that for just a few vectors, it's easy to simply write in a made-up correlation matrix. But I would like to draw about 100 vectors, each standard normals, and all correlated with one another in a random fashion. It turns out that this task is much more difficult than I thought.

I have posted the code below, first for the code that uses my randcorr function, and then for randcorr.ado, which is basically just the mata sub-routine. And it works, for small correlation matrices... up to about 40x40. Diagonals are all 1, and correlation coefficients (off-diags) fall between -0.4 and 0.4, drawn from a normal distribution. But here is the problem: certain, randomly drawn correlation matrices will NOT be positive semi-definite, even though they are symmetric, full rank, and have all off-diagonal values between -1 and 1. They look like correlation matrixes, but they are not.

I dealt with this problem by checking the eigenvalues, after the construction of the correlation matrix, within the mata sub-routine of my .ado file. If the smallest eigenvalue is less than 0, I draw a new correlation matrix, so that the final correlation matrix handed back to randcorr will be PSD. That works... but as the matrix gets bigger (my parameter N) or as the vectors become more collinear (my parameter s, set in the code to be 0.1), the mata sub-routine has to draw more and more matrices before it finds a PSD one.

So, if you run the code below with N=10 through N=40, it runs quite quickly. If you run the code w/ N=43 it takes a bit, and N=45 goes forever. I suspect the non-PSD problem relates to the transitiveness of correlations... the 43rd correlation coefficient is surely defined largely by the 1st-42rd correlation coefficients, in a way that I am not modeling.

I'm wondering 2 things.

Thanks! Code below, and randcorr.ado below that.

Code:

clear clear all set more off set matsize 10000 local N = 10 /* set number of IVs / size of corr matrix */ matrix M = J(1,`N',0) /* vector of means (all IVs centered at 0) */ randcorr `N' .1 /* correlation matrix generated by randcorr.ado */ global Z z1 /* global for all IVs to be drawn */ forval i = 2/`N' { global Z $Z z`i' } ** Draw the N IVs, according to correlation matrix and mean vector drawnorm $Z , n(1000) corr(corr) means(M)

Code:

program randcorr version 14.2 args n s mata: myfunction(`n',`s') end version 14.2 mata: void myfunction(n,s) { iok=0 while (iok==0) { corr = diag(J(1,n,1)) for (j=1; j<=n; j++) { for (i=j+1; i<=n; i++) { corr[i,j]= rnormal(1,1,0,s) corr[j,i]= corr[i,j]; } } rnk = rank(corr) eigenv =symeigenvalues(corr) imn = minmax(eigenv)[1,1] if (rnk ==n & imn>0) { iok=1 } } st_matrix("corr", corr) } end

( invalid name

r(198);

When running this:

Code:

postfile `sim' beta sd using dem, replace reg hpayday kids xtnw xtinc_pc post `sim' (_b[kids]) (_se[kids])

Code:

postfile `sim' beta sd using dem, replace reg hpayday kids xtnw xtinc_pc post `sim' (`=_b[kids]') (`=_se[kids]')

1

+----------------+

1 | -.4755687238 |

2 | -7.845191301 |

3 | -7.976995867 |

4 | -7.968100143 |

5 | -8.008870078 |

6 | -7.995388117 |

7 | -7.982097707 |

8 | -7.985624132 |

9 | -7.972667072 |

10 | -7.95900065 |

11 | -7.966202475 |

12 | -7.980775105 |

13 | -7.967044048 |

+----------------+

I have determined the smallest element of this matrix with

colmin(b[.,1])

It is equal to -8.008870078. Now I want MATA to determine the column-number of -8.008870078, which is 5. How can I do this?

Sorry, this might be a typical beginner question! But I can't find a solution to my problem in the manual. Thanks a lot for any help!

John]]>

metan aexposed anoexposed bexposed benoexposed, random or by (controlsource) label(namevar = firstauthor)textsize(150)xlabel(0.1,10,600) favours(female # male) nooverall

Any suggestions from you would be very much appreciated.]]>

I am trying to solve a system of equations of the form :

Code:

Ai = Bi [Xi - Sum {Bi*Xi}]

I am trying to use the procedure described in https://www.stata.com/support/faqs/p...ear-equations/, but I have 30 equations here. Is there a simple way to code this in Mata.

Any help is much appreciated.

Thank you]]>