2

Say I have a "seed" SparseArray e.g. m=SparseArray[{1->1}]. How do I add a rule at a position that has not yet been defined e.g. 5->5to get a list of rules {1}->1, (5)->5? I want to build up the sparse array an element at a time. I don't want to have to normalise it as that would appear to defeat the purpose of sparse arrays

It seems like this should be simple.

David G
  • 629
  • 4
  • 6

1 Answers1

4

You need to tell the SparseArray how large it will be when you initialize it, then you can just use Part and Set to update it:

m = SparseArray[{1 -> 1}, {10}];
m[[3]] = 3
(* 3 *)

Head@m
(* SparseArray *)

Normal@m
(* {1, 0, 3, 0, 0, 0, 0, 0, 0, 0} *)

From the comments, I would suggest that an Association is a better data structure for this purpose. You can build it up efficiently, and quickly dump it to a SparseArray at the end,

data = <|1 -> 2|>;

(* do something *)
data[4] = 22;
(* do something else *)
data[233] = 55;
(* now that you are done, make a SparseArray *)
SparseArray[ Normal @ data]
(* SparseArray[Automatic, {233}, 0, {
 1, {{0, 3}, {{1}, {4}, {233}}}, {2, 22, 55}}] *)

It will work for a higher dimension array,

data = <|{1, 1} -> 2|>;
data[{45, 33}] = 22;
data[{1000, 233}] = 55;
SparseArray[ Normal @ data]

enter image description here

You can access the stored values, and provide a default value just like for an array

Lookup[data, Key[{1000, 233}], 0]
(* 55 *)

Lookup[data, Key[{1000, 234}], 0]
(* 0 *)
Jason B.
  • 68,381
  • 3
  • 139
  • 286
  • But I don't know how big it will be. I suppose if its internal representation is the least bit efficient I could initialise it to, say, a million elements without incurring too much of a penalty, but that seems ugly. – David G Jun 15 '18 at 17:58
  • 4
    I wonder then if SparseArray is the right tool to use for this, see the edit – Jason B. Jun 15 '18 at 18:08
  • I think that you may well be correct. Thanks. – David G Jun 15 '18 at 20:18