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$
5
  • 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
    Commented Apr 12, 2015 at 22:53
  • $\begingroup$ The CSI matrix could look something like this: $\endgroup$
    – johnhenry
    Commented Apr 12, 2015 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
    Commented Apr 12, 2015 at 23:07
  • 2
    $\begingroup$ Use Table, not For. $\endgroup$
    – Michael E2
    Commented Apr 12, 2015 at 23:18
  • $\begingroup$ Your code produces a symmetric matrix (right?) but your example CSI is not symmetric. $\endgroup$
    – kglr
    Commented Apr 13, 2015 at 6:28

2 Answers 2

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$
3
  • $\begingroup$ very nice...always learning :) $\endgroup$
    – ubpdqn
    Commented Apr 13, 2015 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
    Commented Apr 13, 2015 at 6:23
  • 1
    $\begingroup$ indeed...just was trying to facilitate either clarification or self-directed action...either way progress $\endgroup$
    – ubpdqn
    Commented Apr 13, 2015 at 6:25

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