1
$\begingroup$

I need to fill a matrix, CSI, by taking elements from an array, inverse, which is the Inverse Fast Fourier Transform of an array called powerspectrum. The way the CSI matrix is filled is by creating "bands" according to the following Python code:

CSI = zeros((n, n))
for i in range(n):
    for j in range(n):
        if abs(j-i) < (n/2):
            CSI[i][j] = inverse[abs(i-j)]
        else:
            CSI[i][j] = 0

where I first initialize the matrix CSI setting its values to 0 and then I fill the bands. I must do the same in Mathematica. How can I do that? Here is what I have tried so far, but it does not work:

inverse = InverseFourier[pts];
CSI = SparseArray[{For[j = 1, j < n/2 + 1, ++j,
                        Band[{1, j}] -> inverse[[Abs[i - j]]]]}, {n, n}]
$\endgroup$

closed as unclear what you're asking by ciao, Jens, bbgodfrey, m_goldberg, Karsten 7. Apr 13 '15 at 9:13

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 2
    $\begingroup$ Provide a minimal example with data examples for input and result. Readers should not have to infer such things, nor decode non-Mathematica code. $\endgroup$ – ciao Apr 12 '15 at 22:53
  • $\begingroup$ The CSI matrix could look something like this: $\endgroup$ – johnhenry Apr 12 '15 at 23:06
  • $\begingroup$ { {5.19697, 1.5303, 0, 0}, {5.80303, 11.6667, 1.5303, 0}, {0, 5.80303, 11.6667, 1.5303}, {0, 0, 5.80303, 6.4697}} $\endgroup$ – johnhenry Apr 12 '15 at 23:07
  • 2
    $\begingroup$ Use Table, not For. $\endgroup$ – Michael E2 Apr 12 '15 at 23:18
  • $\begingroup$ Your code produces a symmetric matrix (right?) but your example CSI is not symmetric. $\endgroup$ – kglr Apr 13 '15 at 6:28
3
$\begingroup$

I post this in case it is of assistance:

func[mat_] := Module[{n = Length[mat], tup},
  tup = Cases[Tuples[Range[n], 2], {i_, j_} /; Abs[i - j] < (n - 1)/2];
  SparseArray[
   Thread[tup -> (mat[[Abs[#1 - #2] + 1]] & @@@ tup)], {n, n}]]

This produces sparse array for an array input (in your case "inverse") and I have tried to to take account Python arrays starting at 0.

As a test and perhaps to allow you to achieve your desired result:

tf[n_] := 
 With[{u = Range[n]}, 
  Row[{u // MatrixForm, "->", Normal@func[u] // MatrixForm}, 
   Frame -> True]]
Grid[Partition[tf /@ Range[3, 9], 2], Frame -> All]

I have done it this way so you can see what elements are chosen.

There are many ways to accomplish desired goal in Mathematica. Play and use of Wolfram resources and this site are invaluable.

enter image description here

$\endgroup$
3
$\begingroup$

Assuming ubpdqn's translation holds, this should be a much faster route to the same result:

f = With[{n = Length@#}, ToeplitzMatrix[PadRight[Take[#, Floor[n/2]], n]]] &;

Quick perf. comparo of Func, using Table, and f (on loungebook):

enter image description here

$\endgroup$
  • $\begingroup$ very nice...always learning :) $\endgroup$ – ubpdqn Apr 13 '15 at 6:10
  • 1
    $\begingroup$ @ubpdqn: Thank you, of course if our guess on result is wrong, for naught... and +1 back at you - nice presentation as always. $\endgroup$ – ciao Apr 13 '15 at 6:23
  • 1
    $\begingroup$ indeed...just was trying to facilitate either clarification or self-directed action...either way progress $\endgroup$ – ubpdqn Apr 13 '15 at 6:25

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