python generate a infinite list with certain condition - python

I know there is generator yield in python like:
def f(n):
x = n
while True:
yield x
x = x+1
So I try to convert this haskell function into python without using iterate: Haskell infinite recursion in list comprehension
I'm not sure how to define base case in python, also not sure how to combine if statement with this yield staff! here is what I try to do:
def orbit(x,y):
while True:
yield p (u,v)
p (u,v) = (u^2 - v^2 + x, 2 * u * v + y)

I dont see where you're getting the p from. As far as I can see you can almost literally translate it from Haskell:
def orbit(x, y):
u, v = 0, 0
while True:
u, v = u**2 − v**2 + x, 2*u*v + y
yield u, v
In their example, calling the function as orbit(1, 2), u will be bound to 1 and v to 2 in the first round, then that ((1, 2)) is yielded. In the next iteration, u = 1**2 - 2**2 + 1 = 1 - 4 + 1 = -2 and v = 2*1*2 + 2 = 6.

Related

How do I write a Python code for partial fraction decomposition without using "apart"?

So I am very unexperienced with Python, I know basically nothing, and our teacher gave us the task to write a code that makes a partial fraction decomposition with this function:
I don't really know how to start or even how to define that function. I tried this at first: `
def function(x):
a = (x^4)-(3*x^2)+x+5
b = (x^11)-(3*x^10)-(x^9)+(7*x^8)-(9*x^7)+(23*x^6)-(11*x^5)-(3*x^4)-(4*x^3)-(32*x^2)-16
return a/b
But our maths script says that we need to split up the denominator and then make a system of equations out of it and solve it.
So I was thinking about defining each part of the function itself and then make a function somehow like a = 7*x and use it like f(x) = b/a^7 if this works but I don't really know. We are unfortunately not allowed to use "apart" which I think is a sympy-function?
Thank you so much in advance!
Sincerely, Phie
Addition: So after a few hours of trying I figured this. But I am very sure that this is not the way to do it. Also it tells me that variable l is not defined in z and I am sure that all the others aren't as well. I don't know what to do.
def function(x):
global a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v
a = (x^4)-(3*x^2)+x+5
b = 11
c = 10
d = 9
e = 8
f = 7
g = 6
h = 5
i = 4
j = 3
k = 2
l = x**b
m = 3*x**c
n = x**d
o = 7*x**e
p = 9*x**f
q = 23*x**g
r = 11*x**h
s = 3*x**i
t = 4*x**j
u = 32*x**k
v = 16
return a/(l-m-n+o-p+q-r-s-t-u-v)
print("We are starting the partial fraction decomposition with this
function: (x^4)-(3*x^2)+x+5 / (x^11)-(3*x^10)-(x^9)+(7*x^8)-(9*x^7)+
(23*x^6)-(11*x^5)-(3*x^4)-(4*x^3)-(32*x^2)-16")
z = l-m-n+o-p+q-r-s-t-u-v
while c >= 0:
c = c-1
z = z-l
while d >= 0:
d = d-1
z = z-m
while e >= 0:
e = e-1
z = z-n
while f >= 0:
f = f-1
z = z+o
while g >= 0:
g = g-1
z = z-p
while h >= 0:
h = h-1
z = z+q
while i >= 0:
i = i-1
z = z-r
while j >= 0:
j = j-1
z = z-s
while k >= 0:
k = k-1
z = z-t
print(z)
Since I just solved this myself, here's some input:
Let poly = function() for your function, although be careful to replace ^ with **. Include both from sympy import * and from sympy.abc import a, b, c, d, e, f, g, h, i, j, k, x.
Using factor(exp) you can find all the roots of your function, use these to define the 11 terms term_1 = a/(x-2), term_2 = b/(x2-)**2, ... , term_6 = (f*x + g)/(x**2 +1), ..., term_8 = (j*x + k)/(x**2 + 1) (you get the gist). Define your_sum = term_1 + ... + term_8, eq = Eq(your_sum, poly)
Define the variable your_sum = sum(term_1, ..., term_8), and use solve_undetermined_coeffs(eq, [a,b, ..., k], x))) to get the result.

Memory limit exceeded in Python

I am solving a problem that needs either a list of integers or a dictionary of size 10^18. Upon running the code the compiler throws an error message saying "Memory Limit Exceeded".
Here is my code:
def fun(l, r, p):
#f = [None, 1, 1]
f = {0:0, 1:1, 2:1}
su = 0
for i in range(1, r):
if i%2 == 0:
f[i+2] = 2*f[i+1] - f[i] + 2
#f.append(2*f[i+1] - f[i] + 2)
else:
f[i+2] = 3*f[i]
#f.append(3*f[i])
for k in range(l, r):
su = su + f[k]
su = (su + f[r]) % p
print(su)
t, p = input().split()
p = int(p)
t = int(t)
#t = 3
#p = 100000007
for i in range(t):
l , r = input().split()
l = int(l)
r = int(r)
fun(l, r, p)
It is showing memory limit exceeded with a maximum memory usage of 306612 KiB.
Two observations here:
You don't need to store all numbers simultaneously. You can use the deque and generator functions to generate the numbers by keeping track of only the last three digits generated instead of the entire sequence.
import itertools
from collections import deque
def infinite_fun_generator():
seed = [0, 1, 1]
dq = deque(maxlen=2)
dq.extend(seed)
yield from seed
for i in itertools.count(1):
if i % 2 == 0:
dq.append(2 * dq[-1] - dq[-2] + 2)
else:
dq.append(3 * dq[-2])
yield dq[-1]
def fun(l, r, p):
funs = itertools.islice(infinite_fun_generator(), l, r + 1)
summed_funs = itertools.accumulate(funs, lambda a, b: (a + b) % p)
return deque(summed_funs, maxlen=1)[-1]
You might have a better chance asking this in Math.SE since I don't want to do the math right now, but just like with the Fibonacci sequence there's likely an analytic solution that you can use to compute the nth member of the sequence analytically without having to iteratively compute the intermediate numbers and it may even be possible to analytically derive a formula to compute the sums in constant time.

Calculate a polynomial

I want to calculate a polynomial on x value. I tried to write
a function that takes as argument an array of integer and integer x
the function will returns the value of the polynomial in x.
def pol(L, x):
P = None
for i in L:
P = L[0] * (x ** 0) + L[1] * (x ** 1) + L[2] * (x ** 2)
return P
L = [0, 2, 4]
x = 3
print(pol(L, x))
I also tried
def pol(L, x):
P = None
for i in L:
j = 0
P = sum(i * (x ** j))
j += 0
return P
L = [0, 2, 4]
x = 3
print(pol(L, x))
It will return 42 for this example.
I don't know how to increment.
Thanks
Building up on your attempts, one straightforward way to get the polynomial would be the following:
def poly(p, x):
val = 0
for i, pp in enumerate(p):
val += pp * x**i
return val
There are faster and more elegant ways to do this, though. I'd strongly encourage you to use numpy.polyval() for efficiency.
Note that for the numpy implementation, p[0] is the highest order polynomial while for the example shown here, p[0] is the lowest order!
p = [0, 2, 4]
x = 3
poly(p, x)
>> 42
import numpy as np
poly(p, x) == np.polyval(p[::-1], x)
>> True

Looping the Fibbonacci Sequence in Python

I am writing a program in Python 2.7.6 that calculates the Fibonacci Sequence(1,1,2,3,5,8,etc.). This is the code(so far):
x = int(input("Enter a number: "))
y = int(input("Enter the number that comes before it:"))
z = x + y
a = z + x
b = a + z
c = b + a
d = c + b
e = d + c
f = e + d
g = f + e
print x, z, a, b, c, d, e, f, g
Is there a way I can loop the process so that I don't have to keep typing f=e+d and others?
Sure, just use some form of loop. For example, if you want to make a list of the first 11 Fibonacci numbers after x:
fiblist = [x]
for _ in range(10):
z = x + y
fiblist.append(z)
x, y = z, x
print(fiblist)
(or use a loop instead of the single print to vary the output's cosmetics -- not relevant to your core Q).
For different purposes (e.g "list all numbers in the sequence until the first one above 100") you could easily tweak the loop (e.g in lieu of the for use while x <= 100:).
You can write a loop or just use the built-in reduce function in Python.
fib = lambda n: reduce(lambda x, y: x+[x[-1]+x[-2]],range(n-2), [0, 1])

writing multiple data calculated from a function in the same file

I am trying to write a data calculated from this function in a file. But the function is called number of times. Say there are 9 numbers in another file and this function will calculate the root for each of those 9 numbers. These 9 roots from this function should be written in the same file. But the way I have done it here will write calculated root in the file but the next one will replace this in the file. There are other mathematical functions that are carried out for each of those 9 numbers before this function is called therefore the functions are called again and again separately.Is it possible to write them all in the same file? Thank you.
def Newton(poly, start):
""" Newton's method for finding the roots of a polynomial."""
x = start
poly_diff = poly_differentiate(poly)
n = 1
counter = 0
r_i = 0
cFile = open("curve.dat", "w")
while True:
if (n >= 0) and (n < 1):
break
x_n = x - (float(poly_substitute(poly, x)) / poly_substitute(poly_diff, x))
if x_n == x:
break
x = x_n # this is the u value corresponding to the given time
n -= 1
counter += 1
x = str(x)
cFile.write('\n' + x + '\n')
if r_i:
print "t(u) = ", (x, counter)
else:
print "t(u) = ", x
cFile.close
After following the suggestions I got I changed the code to the following:
def Newton(poly, start):
""" Newton's method for finding the roots of a polynomial."""
x = start
poly_diff = poly_differentiate(poly)
n = 1
counter = 0
while True:
if (n >= 0) and (n < 1):
break
x_n = x - (float(poly_substitute(poly, x)) / poly_substitute(poly_diff, x))
if x_n == x:
break
x = x_n # this is the u value corresponding to the given time
n -= 1
counter += 1
yield x
Bezier(x)
def Bezier(u_value) :
""" Calculating sampling points using rational bezier curve equation"""
u = u_value
p_u = math.pow(1 - u, 3) * 0.7 + 3 * u * math.pow(1 - u, 2) * 0.23 \
+ 3 * (1 - u) * math.pow(u, 2) * 0.1 + math.pow(u, 3) * 0.52
p_u = p_u * w
d = math.pow(1 - u, 3) * w + 3 * u * w * math.pow(1 - u, 2) + 3 * (1 - u) *\
w * math.pow(u, 2) + math.pow(u, 3) * w
p_u = p_u / d
yield p_u
plist = list (p_u)
print plist
I followed the same thing in the Bezier() function but plist is not created as it doesn't print anything. Please help. Thank you.
Your function does two things: It calculates the roots of a polynomial, and it writes the result to an output file. Functions should ideally do one thing.
So, try breaking this up into a function that receives a polynomial and returns a list containing the roots, and then just write that list to a file in one step.
The simplest way to modify your function would be to replace the lines
x = str(x)
cFile.write('\n' + x + '\n')
with
yield x
Then you can call your function like this:
roots = list(Newton(polynomial, start))
To understand this, read about generators. To write the resulting list to a file, you can use this code:
with open("curve.dat", "w") as output_file:
output_file.write("\n".join(str(x) for x in roots)
While I'm not completely understanding what you are asking I think the answer can be boiled down to:
Open the file in append mode, not in write mode. So instead of
cFile = open("curve.dat", "w")
do
cFile = open("curve.dat", "a")
why use yield in Bezier, it doesn't return multiple values, so you can change:
yield p_u
plist = list (p_u)
print plist
to:
print list(p_u)
return p_u

Categories