Vector Indices: You can do this quite easily by generating vectors of indices and taking advantage of the fact that addition and subtraction are commutative**. For example:
>> i = 4;
>> c = 4321;
>> X = cumsum([0,8*9.^(0:i-2)]);
>> Y = 2*9.^(0:i-1);
>> T = rand(1,1e4);
>> sum(T(c+X)-T(c+X-Y))
ans = 0.736941330376921
And now compare against your method (you can see the 15th digit is different, see ** below):
>> T(c) - T(c-2) + T(c+(8*9^0)) - T(c+(8*9^0 - 2*9^1)) + T(c+(8*9^0)+(8*9^1)) - T(c+(((8*9^0)+(8*9^1) - 2*9^2))) + T(c+(8*9^0)+(8*9^1)+(8*9^2)) - T(c+(((8*9^0)+(8*9^1)+(8*9^2) - 2*9^3)))
ans = 0.736941330376922
How it works: For each susbsequent i value you add new terms, but do not change the existing terms. Lets rearrange your i=4 example so that the terms are aligned in columns:
T(c) - T(c - 2) +
T(c+(8*9^0)) - T(c+(8*9^0 - 2*9^1)) +
T(c+(8*9^0)+(8*9^1)) - T(c+(((8*9^0)+(8*9^1) - 2*9^2))) +
T(c+(8*9^0)+(8*9^1)+(8*9^2)) - T(c+(((8*9^0)+(8*9^1)+(8*9^2) - 2*9^3)))
The Y term is simpler, so lets start with that: it contains the values
Y = [2, 2*9^1, 2*9^2, 2*9^3]
which is just
We can see that the X term is used twice and also involves some kind of cummulative sum. It contains the values
X = [0, 8*9^0, 8*9^0+8*9^1, 8*9^0+8*9^1+8*9^2]
and we notice that each term repeats the previous one plus something new. That new part is just
which is just
and then use cumsum to get the final X vector:
X = cumsum([0,8*9.^(0:i-2)])
The rest is just indexing and addition.
** For numeric computation on binary floating point numbers addition/subtraction are not always commutative, as the results shown above demonstrate. But within reasonable precision we can hold it as being true... as you would anyway not be performing such operations on binary floating point numbers and expecting exact results.
Best Answer