6
$\begingroup$

The most straight forward way for me to think about is like this:

H[N_] := RandomReal[{0,10},{N,N}]
symmetryH[N_]:=(H[N]+H[N]\[Transpose])/2
symmetryH[4]//MatrixForm

However, the above code does not work because the second call of H[N] will generate a different matrix from the first call. How can I get around this side effect?

$\endgroup$

3 Answers 3

11
$\begingroup$

First, you just have to create exactly one H[N] and use this 2 times. This can be achieved by

H[n_] := RandomReal[{0, 10}, {n, n}]
symmetryH[n_] := With[{hn = H[n]},
  (hn + Transpose[hn])/2
]

Second, please do not use N as variable or pattern. It might shoot you in the foot because it is a function in Mathematica.

Finally, you should realize, that your approach contains a very serious flaw. What makes you believe, that you can calculate the mean of your matrix and its transpose while still maintain the same distribution for your randomness? Let us make a very quick example, where we create 1000 of your random matrices:

data = Table[symmetryH[4], {1000}];

Now, let us look on all upper left elements and plot their histogram

Histogram[data[[All, 1, 1]]]

Mathematica graphics

Exactly what you wanted. Evenly distributed. Let's take a look on the upper right corner

Histogram[data[[All, 1, -1]]]

Mathematica graphics

Uhh, not so nice. This happens because all upper right elements are really the mean of two different numbers, while the upper left elements are the mean of the same number.

$\endgroup$
3
  • $\begingroup$ You are very quick! :) $\endgroup$ Jan 24, 2016 at 6:54
  • $\begingroup$ Sorry. Saw it and thought I need to clear this up as quick as possible so that no one believes it is a good way. $\endgroup$
    – halirutan
    Jan 24, 2016 at 6:55
  • $\begingroup$ Thank you for pointing this out. $\endgroup$ Jan 24, 2016 at 7:04
9
$\begingroup$

This one prevents the distribution problems halirutan is talking about:

h[n_] :=
 Module[{m},
  m = RandomReal[{0, 10}, {n, n}];
  m SparseArray[{i_, j_} /; i >= j -> 1, {n, n}] + 
    Transpose[m SparseArray[{i_, j_} /; i > j -> 1, {n, n}]] // Normal
  ]

h[5] // TableForm

Mathematica graphics

Distribution is uniform now:

Histogram@Flatten@h[1000]

Mathematica graphics

$\endgroup$
2
  • 1
    $\begingroup$ Sjoerd, rather than using SparseArray to obtain a lower vs. upper triangular matrix, I found that using LowerTriangularize and UpperTriangularize seems faster (and also more readable, at least to me). For instance, substituting UpperTriangularize[m] + LowerTriangularize[Transpose@m, -1] for your expression seems to give a roughly 100x speedup, at least on my system (v. 10.3). $\endgroup$
    – MarcoB
    Jan 25, 2016 at 5:17
  • $\begingroup$ @marcob you're fully right and I should have remembered this. $\endgroup$ Jan 25, 2016 at 21:11
0
$\begingroup$

One can use the Module to declare a local variable:

H[N_] := RandomReal[{0,10},{N,N}]
symH[N_]:=Module[{h=H[N]},(h+h\[Transpose])/2];
symH[4]//MatrixForm

This should work.

$\endgroup$
1
  • $\begingroup$ No one upvote this poor answer... It is very convenient if one don't cares about the distribution.... $\endgroup$ Jan 25, 2016 at 6:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.