1
$\begingroup$

I want to create an array that must be symmetric with respect to the centre of it, as in the following example:

0 1 2 3 4 3 2 1

but, instead of having such simple numbers in the array, I need to fill the array by extracting the i-th number from a Gaussian distribution with mean 0 and variance equal to a function of the index i. I have tried to use Piecewise, at least to fill the first half of the array, but I don't know how to fill the other half:

KfieldREAL[k_] := Piecewise[{{0, k == 0},
     {RandomVariate[NormalDistribution[mu, Exp[-(2*Pi*k*sigma/L)^2]]], 
     0 < k <= n/2}, (*missing part here*)

How can I create an array like that?

$\endgroup$
1
$\begingroup$

How about creating the left half and using its image for the right half.

sigma = .25; L = 300; mu = 1; n = 1000;

left = Table[{k,RandomVariate[NormalDistribution[mu, Exp[-(2*Pi*k*sigma/L)^2]]]}, {k, n/2}];

right = Reverse[left] /. {x_, y_} -> {n - x, y}; (*imaging*)
full = Join[Most[left], right];
ListPlot[full, Frame -> True]

enter image description here

Adding extra elements

Let say you want to put the element x1 [say, (0,0)] at the beginning or end. You can simply put it during the Join.

x1={0,0.0}; x2={n+1,0.0}; (*first and last element in (k,f(k)) format*)
full=Join[{x1},Most[left], right,{x2}];

Note that when using join, you don't use a single element x1, rather a list containing a single element {x1}.

for n=8 it looks like

$ \begin{array}{l l} 0 & 0.00000 \\ 1 & 1.47757 \\ 2 & 2.29881 \\ 3 & 1.46615 \\ 4 & 1.34819 \\ 5 & 1.46615 \\ 6 & 2.29881 \\ 7 & 1.47757 \\ 9 & 0.00000 \\ \end{array} $

And your list now has n+1 element. This is because the axis of reflection goes through 4. If you want even number of element then use n+1 for right and omit Most in final.

right = Reverse[left] /. {x_, y_} -> {n + 1 - x, y};
full = Join[left, right]; 

And the result for n=8 after adding the zeros

x1 = {0, 0.0}; x2 = {n + 1, 0.0};
full = Join[{x1}, left, right, {x2}];

$ \begin{array}{ll} 0 & 0.00000 \\ 1 & 0.380134 \\ 2 & 1.48306 \\ 3 & 0.509712 \\ 4 & 1.76137 \\ \hline 5 & 1.76137 \\ 6 & 0.509712 \\ 7 & 1.48306 \\ 8 & 0.380134 \\ 9 & 0.00000 \\ \end{array} $

Now 4 and 5 has same element and number of elements in your final list iss n+2.

$\endgroup$
  • $\begingroup$ You could also use full = ArrayPad[left, n/2-1, "Reflected"]. $\endgroup$ – C. E. Apr 13 '15 at 10:14
  • $\begingroup$ Thanks @Pickett. I didn't know about that syntax. $\endgroup$ – Sumit Apr 13 '15 at 10:21
  • $\begingroup$ Thanks to all of you. The method described in @Sumit 's answer works very well, I just need to add the first element, which is 0 (because that's what the theory imposes). How can I do that? I have tried using Join, but I did not succeed in adding a first element, set to 0. $\endgroup$ – johnhenry Apr 13 '15 at 10:52
  • $\begingroup$ Just a wild guess for adding the leading 0: Join[{0},(a = RandomVariate[NormalDistribution[0, 1], i]), Drop[Reverse[a], 1]] Note the curly braces around the zero in the Join function. $\endgroup$ – LLlAMnYP Apr 13 '15 at 11:15
0
$\begingroup$
myMatrix[i_, j_] := 
 Table[Join[(a = RandomVariate[NormalDistribution[0, 1], i]), 
   Drop[Reverse[a], 1]], {j}]

 ListPlot[myMatrix[10, 10], Joined -> True]

enter image description here

$\endgroup$
0
$\begingroup$
ClearAll[kfR]
kfR[mu_: 0, sigma_: 1, L_: 100] := With[{m = Array[
     RandomVariate[NormalDistribution[mu, Exp[-(2 Pi # sigma/L)^2]]] &, Ceiling[#/2]]},
   Prepend[m[[MapThread[Min, {Range[#], Reverse@Range[#]}]]], 0]] &

MatrixPlot[{kfR[][10]}, AspectRatio -> 1/10, ImageSize -> 800,
 ColorFunction -> "TemperatureMap",
 FrameTicks -> {{None, None}, {{#, #-1} & /@ Range[11], {#, #-1} & /@ Range[11]}}]

enter image description here

Using MultinormalDistribution instead of NormalDistribution:

ClearAll[kfR2]
kfR2[mu_: 0, sigma_: 1, L_: 100] := With[{m = ConstantArray[mu, Ceiling[#/2]], 
  s = DiagonalMatrix[Exp[-(2*Pi*Range[Ceiling[#/2]]*sigma/L)^2]], 
  ind = MapThread[Min, {Range[#], Reverse@Range[#]}]}, 
 Prepend[RandomVariate[MultinormalDistribution[m, s]][[ind]], 0]] &;

Panel[Column[MatrixPlot[{aa = (kfR2[][#])}, AspectRatio -> 1/10, 
     ImageSize -> 800, ColorFunction -> "TemperatureMap", 
     FrameTicks -> {{None, None},
       {rng = ({#, # - 1} & /@ Range[# + 1]), rng},
     Epilog -> (MapIndexed[Style[Text[Round[#, .2], {First[#2] - 1/2, 1/2}],
         "Panel", 18, Bold, Background -> Transparent] &, aa])] & /@ 
    {5, 6, 11, 12}]]

enter image description here

$\endgroup$
  • $\begingroup$ thanks for your answer, but unfortunately this is not what I need, because you are changing only the variance of the distribution from which the numbers are extracted in the second half of the array. I need the numbers to be an exact duplicate of the first half, with the symmetry described in my question before $\endgroup$ – johnhenry Apr 13 '15 at 9:21
  • $\begingroup$ @user, i see.. I will post a fixed version, $\endgroup$ – kglr Apr 13 '15 at 9:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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