7
$\begingroup$

I have a list:

{{pos_1,val_1},{pos_2,val_2},...}

and would like to generate an array of dimension d, with values val_i at positionspos_i, the rest being filled with 0. I would assume that I shall use SparseArray but this function has a different form of argument:

{pos_1->val_1,pos_2->val_2,...}

Is there any simple way to transform one type of the argument into the other, or completely different approach shall be undertaken?

$\endgroup$

3 Answers 3

5
$\begingroup$

Another possibility is

SparseArray[Rule @@ Transpose[posval]]

I think the input syntax that gets processed the quickest among the documented ones would be

SparseArray[pos -> vals , dims]

where pos is a list of positions and vals is a list of values. This way, pos and vals can be PackedArrays which can be processed much faster. A list of the form you described cannot be packed in general. So better not generate it this way. Mapping Rule on the position-value pairs also unpacks arrays. Generate pos and vals independently. In general, this will be much faster.

For additive matrix assembly, see also here.

$\endgroup$
4
  • $\begingroup$ Your suggestion works. Thank you! I just have noted another problem. In my array some positions are 0's. For simplicity I would just increment all positions by 1. At which stage it would be most efficient? Is it possible at the stage of generating the SparseArray? $\endgroup$
    – drer
    Commented Feb 28, 2018 at 15:36
  • 1
    $\begingroup$ You can use {pos,vals} = Transpose[posval]; SparseArray[pos+1 -> vals , dims]. This adds 1 onto all positions indices. $\endgroup$ Commented Feb 28, 2018 at 15:54
  • $\begingroup$ Thank you. It works. $\endgroup$
    – drer
    Commented Feb 28, 2018 at 16:45
  • $\begingroup$ You're welcome! $\endgroup$ Commented Feb 28, 2018 at 17:08
5
$\begingroup$
posval = Join[List /@ RandomSample[Tuples[Range[5], {2}], 10], 
   List/@RandomInteger[9, 10], 2]

{{{2, 4}, 3}, {{2, 1}, 8}, {{3, 5}, 4}, {{2, 3}, 3}, {{5, 5}, 4}, {{3, 2}, 8}, {{4, 5}, 8}, {{3, 1}, 6}, {{2, 5}, 2}, {{5, 1}, 8}}

dims = Max /@ Transpose[posval[[All, 1]]];
sa = SparseArray[Rule @@@ posval, dims];

SparseArray[<10>, {5, 5}]

TeXForm @ MatrixForm @ sa

$$\left( \begin{array}{ccccc} 0 & 0 & 0 & 0 & 0 \\ 8 & 0 & 3 & 3 & 2 \\ 6 & 8 & 0 & 0 & 4 \\ 0 & 0 & 0 & 0 & 8 \\ 8 & 0 & 0 & 0 & 4 \\ \end{array} \right)$$

$\endgroup$
4
$\begingroup$

For a list of the form: list={{pos_1,val_1},{pos_2,val_2}}

How about SparseArray[Map[#[[1]] -> #[[2]] &, list]] ?

$\endgroup$
2
  • $\begingroup$ I have tried and got the message List expected at position 1 in SparseArray. Can you give a working example? $\endgroup$
    – drer
    Commented Feb 28, 2018 at 15:22
  • $\begingroup$ sorry made a typo in the equation. I will add a full working example when I get access to MMA again $\endgroup$
    – Dunlop
    Commented Feb 28, 2018 at 15:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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