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$
4
$\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$
  • $\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 Feb 28 '18 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$ – Henrik Schumacher Feb 28 '18 at 15:54
  • $\begingroup$ Thank you. It works. $\endgroup$ – drer Feb 28 '18 at 16:45
  • $\begingroup$ You're welcome! $\endgroup$ – Henrik Schumacher Feb 28 '18 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$
  • $\begingroup$ I have tried and got the message List expected at position 1 in SparseArray. Can you give a working example? $\endgroup$ – drer Feb 28 '18 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 Feb 28 '18 at 15:55

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.