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$

3 Answers 3

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$
4
  • $\begingroup$ You could also use full = ArrayPad[left, n/2-1, "Reflected"]. $\endgroup$
    – C. E.
    Apr 13, 2015 at 10:14
  • $\begingroup$ Thanks @Pickett. I didn't know about that syntax. $\endgroup$
    – Sumit
    Apr 13, 2015 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, 2015 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, 2015 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$
2
  • $\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, 2015 at 9:21
  • $\begingroup$ @user, i see.. I will post a fixed version, $\endgroup$
    – kglr
    Apr 13, 2015 at 9:30

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.