I will repost the code here, so we can refer to same code/line numbers
import math
def fastln(n, x):
a =(1 + x) / 2
g = x ** (1 / 2)
d = [[a]]
for i in range(1, n + 1):
a = (a + g) / 2
g = ((a * g) ** (1 / 2))
d[-1].append(a)
for k in range(1, n + 1):
d.append([])
for i in range(n + 1):
d[k].append((d[k - 1][i] - 2 ** (-2 * k) * d[k - 1][i - 1])/(1 - 2 ** (-2 * k)))
return (x - 1)/d[-1][-1]
print(fastln(4,4))
print(math.log(4, math.e))
print(fastln(5,4))
As I said you need to understand that
d
is list of lists (n lists with n elements - float numbers each), so that it can hold/store calculated values for d(k, n) for all combinations of k and n. I.e. you can consider/call it n X n matrix, 2-dimensional array, whatever term you are familiar with...
(Apr-24-2019, 07:53 PM)mcgrim Wrote: [ -> ]On line 5, I am understanding that you are creating a list 'd', but I don't understand why isn't it an empty list? And why the double brackets?
on line 5 I initialize
d
with one element - empty list and that element/list has one float value that is
a
calculated on previous lines. i.e. that is
a0
that we store in d[0][0] or d(0, 0) = a
0 if we look at the paper, e.g.
>>> a = 2.5 # that's just example, assume a0 is calculated to be 2.5
>>> d = [[a]]
>>> type(d)
<class 'list'>
>>> type(d[0])
<class 'list'>
>>> d[0][0]
2.5
>>>
in slow-motion
d = [[a]]
is the same as
d = [] # create empty list
d.append([]) # append empty list. now d is a list with one element which is empty list
d[0].append(a) # now we append to the first element of d, which is a list, so now d == [[a]]
(Apr-24-2019, 07:53 PM)mcgrim Wrote: [ -> ]On line 9 I can see that you are trying to turn 'a' into a list, but why the '-1' ?
I don't try to turn
a
into a list. I append current calculated value of
a
to last element element of d (remember python allows negative indexes of list and index -1 is the last element). At that time
d
has only one element - one list. Before line 9 this list has only
i number of values, i.e.
len(d[0]) == i
. d has obe element - one list and that list has n float values in it.
Now we need to calculate
If you prefer line 9 could look
d[0].append(a)
From point of view of the paper that is d(0, i) = a
i
(Apr-24-2019, 07:53 PM)mcgrim Wrote: [ -> ]on line 11, why appending the empty list?
after first loop (lines 6-9) is complete we have calculated n values, i.e. all d(0, i) values where i is from 0 to n. (i.e.
for i in range(0, n+1)
Now we use 2 nested loops to calculate rest of the values. we need to add another list to d, so that we can store all d(1, i) values where i is from 0 to n. (i.e.
for i in range(0, n+1)
. After line 11 d will have k+1 elements - i.e. k+1 lists
(Apr-24-2019, 07:53 PM)mcgrim Wrote: [ -> ]on line 13, I can't understand the d[k].append.
As we need to calculate all d(k, n) values, now we calculate the value for respective value of k and i and store it to last element (it has index -1 or k) of d. If you prefer
d[k].append(... here is the big recursive formula...)
you can have
d[-1].append(... here is the big recursive formula...)
here is the code with some extra comments and in smaller steps
def fastln(n, x):
a =(1 + x) / 2
g = x ** (1 / 2)
d = []
d.append([])
d[0].append(a) # you can write also it like this: d[-1].append(a)
for i in range(1, n + 1):
a = (a + g) / 2
g = ((a * g) ** (1 / 2))
d[0].append(a) # you can write also it like this: d[-1].append(a)
# at this point we have calculated all d(0, n) values
# so len(d) == 1
# and len(d[0]) == n
# now start calculating rest d(k, n) values
for k in range(1, n + 1):
d.append([]) # now d has k+1 elements-lists. the last element has index k or -1
for i in range(n + 1):
calculated_value = (d[k - 1][i] - 2 ** (-2 * k) * d[k - 1][i - 1])/(1 - 2 ** (-2 * k))
d[k].append(calculated_value) # you can write also it like this: d[-1].append(calculated_value)
return (x - 1)/d[-1][-1]
In addition, we can write it a bit different if it is easier for you to understand:
def fastln(n, x):
a =(1 + x) / 2
g = x ** (1 / 2)
d = [[] for _ in range(n)]
# at this point d already has n elements, all of them - empty lists, so len(d) == n
d.append([])
d[0].append(a)
for i in range(1, n + 1):
a = (a + g) / 2
g = ((a * g) ** (1 / 2))
d[0].append(a)
# at this point we have calculated all d(0, n) values
# so len(d) == n
# and len(d[0]) == n
# now start calculating rest d(k, n) values
for k in range(1, n + 1):
for i in range(n + 1):
calculated_value = (d[k - 1][i] - 2 ** (-2 * k) * d[k - 1][i - 1])/(1 - 2 ** (-2 * k))
d[k].append(calculated_value)
return (x - 1)/d[-1][-1]
note that in this case we cannot use d[-1].append(), because now d has n elements from the start, so we need to use the exact index when we append. Also we don't need to append empty list in each iteration of the outer loop (for each value of k).
(Apr-24-2019, 07:53 PM)mcgrim Wrote: [ -> ]I can see that you marked your previous code as 'not correct', but when I try it for different n, I obtain almost the same result as your last code, is that perhaps a coincidence?
yes, you may consider it coincidence. i.e. it calculates something, some approximation, but when/how close it will be is unclear.