Depending on how sensitive is your map f
you should notice that 0.1
is a floating-point approximation of 1/10
, which is not equal to 1/10
since the numbers are represented in binary format and that 1/10
can not be written as p/2^q
for some integers p
and q
. So, perhaps (depending on your application, the required speed, the required accuracy,...) you should use the exact (rational) 1/10
instead of the numerical 0.1
. The following example could be convincing:
sage: decimal = 0.1
sage: sum([decimal for i in range(10)])
1.00000000000000
sage: sum([decimal for i in range(10)]) == 1
False
Sage offers a srange
function that produces the list of numbers you want:
sage: srange(1,4, step = 1/10)
[1,
11/10,
6/5,
13/10,
7/5,
3/2,
8/5,
17/10,
9/5,
19/10,
2,
21/10,
11/5,
23/10,
12/5,
5/2,
13/5,
27/10,
14/5,
29/10,
3,
31/10,
16/5,
33/10,
17/5,
7/2,
18/5,
37/10,
19/5,
39/10]
To be compared with:
sage: srange(1,4, step = 0.1)
[1.00000000000000,
1.10000000000000,
1.20000000000000,
1.30000000000000,
1.40000000000000,
1.50000000000000,
1.60000000000000,
1.70000000000000,
1.80000000000000,
1.90000000000000,
2.00000000000000,
2.10000000000000,
2.20000000000000,
2.30000000000000,
2.40000000000000,
2.50000000000000,
2.60000000000000,
2.70000000000000,
2.80000000000000,
2.90000000000000,
3.00000000000000,
3.10000000000000,
3.20000000000000,
3.30000000000000,
3.40000000000000,
3.50000000000000,
3.60000000000000,
3.70000000000000,
3.80000000000000,
3.90000000000000]
Be careful, that the last value (4
in this case) is not produced by default. If you want it, you should use the include_endpoint
option:
So, you can get your sum as either:
sage: decimal = 0.1
sage: sum([f(i) for i in srange(1, 4, step=decimal, include_endpoint=True)])
or,
sage: decimal = 1/10
sage: sum([f(i) for i in srange(1, 4, step=decimal, include_endpoint=True)])
In that way, both the lists [f(i) for i in srange(1,4, step=decimal, include_endpoint=True)]
and srange(1,4, step=decimal, include_endpoint=True)
are produced and stored in memory befire the sum is computed. If, instead of 4
you plan to use a very big number, you may want to avoid storing them but only sum them, you can use iterators instead of lists, it suffice to replace srange
with xsrange
and [...]
with (...)
, so you could write:
sage: sum((f(i) for i in xsrange(1, 4, step=decimal, include_endpoint=True)))