3
$\begingroup$

I want to update a vector like this:

list = {0, 0, 0, 0};
updval = {1, 1, 1};
updind = {2, 2, 3};
list[[updind]] += updval;
list

The result is {0, 1, 1, 0}, but should be {0, 2, 1, 0}. The problem are the repeated indices in updind.

How can one do this correctly and fast?

The lists are on the order of kilobytes, but many such assignments need to be done.

$\endgroup$
2
$\begingroup$

The following will do it:

MapThread[(list[[#1]] += #2) &, {updind, updval}]
list
(*  {0, 2, 1, 0}  *)

This will be much faster on large arrays of machine-size integers:

Compile[
  {{list0, _Integer, 1}, {updind, _Integer, 1}, {updval, _Integer, 1}},
  Module[{list = list0},
   MapThread[(list[[#1]] += #2) &, {updind, updval}];
   list
   ]][list, updind, updval]
$\endgroup$
1
  • $\begingroup$ Thanks. I had a similar solution using Scan, but way too slow, so I then used Compile with For loops, which should be comparable to your second suggestion. I'm still wondering though whether there is a clever Mathematica construct that is significantly faster than the Scan/MapThread at least. $\endgroup$ – mrupp Nov 5 '16 at 3:00

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.