I need to construct a vector similar to:
v[x_]:={0, 0, x, 0, 0, 2*x, 0, 0, 3*x, ....., 0, 0, n*x};
where n=10^9
. How can I make such a vector wisely?
Answer
When n is large and x is known, using a PackedArray may be a good option.
ar3=ConstantArray[0,3n];
ar3[[3;;;;3]]=Range[x, n x, x];
ar3
To see that the result is a PackedArray
, we see that
<< Developer`;
PackedArrayQ[ar]
True
Whereas for Kuba's last array we would have False
(even if x has a value). Note that ConstantArray
also produces a PackedArray
.
Whether this is useful really depends on what you want to do with the List
. PackedArray
s take up less space in memory, which is an advantage, but they probably take up more space than a SparseArray
(in this case). Computations using PackedArray
s can be much faster as well.
Some timings/comparisons
I mainly compare my code with Kuba's MapAt
answer. I also compare with my original answer, found further below.
x = 5;
i = 0;
n = 1000000;
(
ar = ConstantArray[0, 3 n];
Do[
ar[[3 i]] = i x
,
{i, 1, n}
];
ar) // Timing // First
(ar2 = MapAt[(++i; i x) &, ConstantArray[0, 3 n], 3 ;; ;; 3]) //
Timing // First
(ar3 = ConstantArray[0, 3 n];
ar3[[3 ;; ;; 3]] = Range[x, n x, x];
ar3
) // Timing // First
3.125590
3.139499
0.048840
So generating the PackedArray
can be considerably faster, if done right. ar1 and ar3 must be the same as they are Equal
and both PackedArray
s, but I added timings/comparisons using both these anyway.
ByteCount[ar]
ByteCount[ar2]
ByteCount[ar3]
24000144
72000080
24000144
which is in favor of the PackedArray
. Doing calculations may also be faster using a PackedArray, like in the following example
ar // Total // Timing
ar2 // Total // Timing
ar3 //Total //Timing
{0.010633, 2500002500000}
{0.629586, 2500002500000}
{0.012352, 2500002500000}
Original answer
Note: It now turns out this use of Do is not so nice
This is very similar to Kuba's answer with MapAt
. But I think Do
works better with PackedArray
s. The following gives a "list" of the required form.
n = 500;
ar = ConstantArray[0, 3 n];
Do[
ar[[3 i]] = i x
,
{i, 1, n}
];
ar
Comments
Post a Comment