Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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?

share|improve this question
up vote 10 down vote accepted

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.

share|improve this answer
    
You are very quick! :) – Oleksandr R. Jan 24 at 6:54
    
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. – halirutan Jan 24 at 6:55
    
Thank you for pointing this out. – buzhidao Jan 24 at 7:04

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

share|improve this answer
1  
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). – MarcoB Jan 25 at 5:17
    
@marcob you're fully right and I should have remembered this. – Sjoerd C. de Vries Jan 25 at 21:11

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.

share|improve this answer
    
No one upvote this poor answer... It is very convenient if one don't cares about the distribution.... – buzhidao Jan 25 at 6:00

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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