Calculate the value of a function for given coordinates - python

I am new here. I want to write a neat litte program to check the solutions of my exam preparations as my professor didnt provide any. For a non- linear differential equation f I want to find the 1st Taylor polynomial. Therefore I take the derivative of f in respect to every variable.
Now my problem:
I have to calculate the value of each derivative for a certain given point. How can I do that for such complex expressions that are just stored in a variable and not explicitly known, as they are calculated?
This is what i do now, without evaluating:
f = input('Enter function: ')
fy1 = diff(f,y1)
fy = diff(f,y)
fu2 = diff(f,u2)
fu1 = diff(f,u1)
fu = diff(f,u)
I tried this function as I hoped it would recognize the variables in f automatically:
def calculate(f,y1,y,u2,u1,u):
return f
...
fy1 = calculate(diff(f,y1),0,-1,0,0,-4)
fy = calculate(diff(f,y),0,-1,0,0,-4)
fu2 = calculate(diff(f,u2),0,-1,0,0,-4)
fu1 = calculate(diff(f,u1),0,-1,0,0,-4)
fu = calculate(diff(f,u),0,-1,0,0,-4)
Edit:
I tried out something else:
For f= -5yy1+4*y-u (y1 is the derivative of y)
fy1 is the derivative of f in respect to y1:
fy1= diff(f, y1)
fy1.subs([(y1,0),(y,-1),(u2,0),(u1,0),(u,-4)])
print("{}".format(fy1))
But subs() didnt substitute any values as the output was the following:
-5*y
I guess it has something to so with the variables being defined as sympy symbols?
y1 = symbols('y1')
y = symbols('y')
u2 = symbols('u2')
u1 = symbols('u1')
u = symbols('u')
But I need that for the sympy diff()-function

My solution for now is almost what I wrote in my first edit. What I didnt realize was that the substitution is not permanent and I had to store the solution in an extra variable.
Here is the complete program. I am open for suggestions to improve it an all aspects.
from sympy import diff, symbols
again = True
while(again):
y1 = symbols('y1')
y = symbols('y')
u2 = symbols('u2')
u1 = symbols('u1')
u = symbols('u')
f = input('Enter function: ')
fy1= diff(f, y1)
res_fy1 = fy1.subs([(y1,0),(y,-1),(u2,0),(u1,0),(u,-4)])
print("{}".format(res_fy1))
fy= diff(f, y)
res_fy = fy.subs([(y1,0),(y,-1),(u2,0),(u1,0),(u,-4)])
fu2= diff(f, u2)
res_fu2 = fu2.subs([(y1,0),(y,-1),(u2,0),(u1,0),(u,-4)])
fu1= diff(f, u1)
res_fu1 = fu1.subs([(y1,0),(y,-1),(u2,0),(u1,0),(u,-4)])
fu= diff(f, u)
res_fu = fu.subs([(y1,0),(y,-1),(u2,0),(u1,0),(u,-4)])
print('delta_y2 + (' + str(res_fy1) + ')*delta_y1 + (' + str(res_fy) + ')*delta_y + (' + str(res_fu2) + ')*delta_u2 + (' + str(res_fu1) + ')*delta_u1 + (' + str(res_fu) + ')*delta_u')
wrongInput = True
while (wrongInput):
i = input('Another function? [y/n] ')
if (i == 'n'):
again = False
wrongInput = False
elif (i == 'y'):
wrongInput = False
else:
print('Wrong Input!')

Related

how do I identify sequence equation Python

Am I able to identify sequence, but not formula
I have the whole code
def analyse_sequence_type(y:list[int]):
if len(y) >= 5:
res = {"linear":[],"quadratic":[],"exponential":[],"cubic":[]}
for i in reversed(range(len(y))):
if i-2>=0 and (y[i] + y[i-2] == 2*y[i-1]): res["linear"].append(True)
elif i-3>=0 and (y[i] - 2*y[i-1] + y[i-2] == y[i-1] - 2*y[i-2] + y[i-3]): res["quadratic"].append(True)
for k, v in res.items():
if v:
if k == "linear" and len(v)+2 == len(y): return k
elif k == "quadratic" and len(v)+3 == len(y): return k
return
print(f"A relation cannot be made with just {len(y)} values.\nPlease enter a minimum of 5 values!")
return
I can identify linear and quadratic but how do I make a function
So, firstly we will need to create two functions for linear and quadratic (formulae attached below).
def linear(y):
"""
Returns equation in format (str)
y = mx + c
"""
d = y[1]-y[0] # get difference
c = f"{y[0]-d:+}" # get slope
if d == 0: c = y[0] - d # if no difference then intercept is 0
return f"f(x) = {d}x {c} ; f(1) = {y[0]}".replace("0x ","").replace("1x","x").replace(" + 0","");
We apply a similar logic for quadratic:
def quadratic(y):
"""
Returns equation in format (str)
y = ax² + bx + c
"""
a = logic_round((y[2] - 2*y[1] + y[0])/2) # get a
b = logic_round(y[1] - y[0] - 3*a) # get b
c = logic_round(y[0]-a-b) # get c
return f"f(x) = {a}x² {b:+}x {c:+} ; f(1) = {y[0]}".replace('1x²','x²').replace('1x','x').replace(' +0x','').replace(' +0','')
If you try the code with multiple inputs such as 5.0 you will get 5.0x + 4 (example). To omit that try:
def logic_round(num):
splitted = str(num).split('.') # split decimal
if len(splitted)>1 and len(set(splitted[-1])) == 1 and splitted[-1].startswith('0'): return int(splitted[0]) # check if it is int.0 or similar
elif len(splitted)>1: return float(num) # else returns float
return int(num)
The above functions will work in any way provided that the y is a list where the domain is [1, ∞).
Hope this helps :) Also give cubic a try.

How do you split a string after a symbol in python?

import sympy
equation = input('Enter an equation: ')
a = equation.split(('=') or ('<') or ('>') or ('<=') or ('>=') or ('==') or ('!='))[0:2]
b = sympify(a[0])
c = sympify(a[1])
d = simplify(b - c)
print('This is the equation simplified: ' + str(d))
I want to split the equation in two parts when one of the symbols (=,<,>,>=,<=,==,!=) appear, but in this code it only works when the '=' sign is the symbol.
I think your code should be like that:
import re #<--- add this
import sympy
equation = input('Enter an equation: ')
a = re.split(r'[=|<|>|<=|>=|==]', equation)[0:2] #<--- only change this
b = sympify(a[0])
c = sympify(a[1])
d = simplify(b - c)
print('This is the equation simplified: ' + str(d))

Python output formatting issues

Not sure about the syntax of the output I am receving. Any help would be appreciated.
Here is my code:
import numpy
def g(): #generate random complex values
return numpy.random.random(1) + numpy.random.random(1) *1j
p = numpy.poly1d(numpy.squeeze([g(),g(),g()])) # test function p
pprime = numpy.polyder(p) #derivative of p
print 'Our p(x) is {} '. format(p)
print('\n') # new line
print'Our pprime(x) is {} '. format(pprime) #apply newtons method to p
print('\n') # new line
#apply newtons method to p
def root_newton ( f, df, tolerance = 1.0e-6):
dx = 2 * tolerance
x=0
while dx > tolerance:
x1 = x - f(x)/df(x)
dx = abs (x - x1)
x = x1
return x
print('Our first root is at {}'.format(root_newton(p,pprime)))
print('\n') # new line
Here's the output:
Our p(x) is 2
(0.6957 + 0.683j) x + (0.3198 + 0.5655j) x + (0.9578 + 0.1899j)
Our pprime(x) is
(1.391 + 1.366j) x + (0.3198 + 0.5655j)
Our first root is at (0.00925817978737+0.830966156841j)
The correct roots are [-0.64968928-1.01513333j 0.00925818+0.83096616j]
What does the 2 above the second component in my first line outputted mean? I can't find anything similar to my question online. I am guessing it may mean the x component is squared but I'm not sure? This is python 3 by the way.
The 2 is the exponent on the first x, misaligned because you put text before it on the same line.
If we take your output:
Our p(x) is 2
(0.6957 + 0.683j) x + (0.3198 + 0.5655j) x + (0.9578 + 0.1899j)
and remove the text you prepended:
2
(0.6957 + 0.683j) x + (0.3198 + 0.5655j) x + (0.9578 + 0.1899j)
the intended meaning of the 2 becomes clearer.

scipy.optimize minimize not changing value. think it's due to late binding but unsure how to change...

I'm fairly new to this but will try and be as clear as possible.
Essentially I have 5 different lists of lists. 4 are imported from txt files and the 5th is a merger of the 4. Each inner list contains a value at index position 3. My objective is to maximize the sum by picking appropriately.
I also have a couple constraints:
The sum of the values at index 6 position can't exceed 50000
I pick 2 items from set C, 3 from set W, 2 from set D, 1 from set G, and 1 from set U (the combined) and I can't pick the same item for each set. Ie. each pick in W has to be different.
My code is below. I'm having trouble in that the optimizer just spits out my initial list of picks. Looking at the data though, I know for sure there are better solutions. I read that the issue may be related to late binding but I'm not sure if that's right and if it is, not sure how to update to fix error either. Appreciate any help. Thanks!
Read: Scipy.optimize.minimize SLSQP with linear constraints fails
import numpy as np
from scipy.optimize import minimize
C = open('C.txt','r').read().splitlines()
W = open('W.txt','r').read().splitlines()
D = open('D.txt','r').read().splitlines()
G = open('G.txt','r').read().splitlines()
def splitdata(file):
for index,line in enumerate(file):
file[index] = line.split('\t')
return(file)
def objective(x, sign=-1.0):
x = list(map(int, x))
pos = 3
Cvalue = float(C[x[0]][pos]) + float(C[x[1]][pos])
Wvalue = float(W[x[2]][pos]) + float(W[x[3]][pos]) + float(W[x[4]][pos])
Dvalue = float(D[x[5]][pos]) + float(D[x[6]][pos])
Gvalue = float(G[x[7]][pos])
Uvalue = float(U[x[8]][pos])
grand_value = sign*(Cvalue + Wvalue + Dvalue + Gvalue + Uvalue)
#print(grand_value)
return grand_value
def constraint_cost(x):
x = list(map(int, x))
pos = 6
Ccost = int(C[x[0]][pos]) + int(C[x[1]][pos])
Wcost = int(W[x[2]][pos]) + int(W[x[3]][pos]) + int(W[x[4]][pos])
Dcost = int(D[x[5]][pos]) + int(D[x[6]][pos])
Gcost = int(G[x[7]][pos])
Ucost = int(U[x[8]][pos])
grand_cost = 50000 - (Ccost + Wcost + Dcost + Gcost + Ucost)
#print(grand_cost)
return grand_cost
def constraint_C(x):
if x[0] == x[1]:
return 0
else:
return 1
def constraint_W(x):
if x[2] == x[3] or x[2] == x[4] or x[3] == x[4]:
return 0
else:
return 1
def constraint_D(x):
if x[5] == init[6]:
return 0
else:
return 1
con1 = {'type':'ineq','fun':constraint_cost}
con2 = {'type':'ineq','fun':constraint_C}
con3 = {'type':'ineq','fun':constraint_W}
con4 = {'type':'ineq','fun':constraint_D}
con = [con1, con2, con3, con4]
c0 = [0,1]
w0 = [0,1,2]
d0 = [0,1]
g0 = [0]
u0 = [0]
init = c0+w0+d0+g0+u0
C = splitdata(C)
W = splitdata(W)
D = splitdata(D)
G = splitdata(G)
U = C + W + D + G
sol = minimize(objective, init, method='SLSQP',constraints=con)
print(sol)

What's wrong with my Extended Euclidean Algorithm (python)?

My algorithm to find the HCF of two numbers, with displayed justification in the form r = a*aqr + b*bqr, is only partially working, even though I'm pretty sure that I have entered all the correct formulae - basically, it can and will find the HCF, but I am also trying to provide a demonstration of Bezout's Lemma, so I need to display the aforementioned displayed justification. The program:
# twonumbers.py
inp = 0
a = 0
b = 0
mul = 0
s = 1
r = 1
q = 0
res = 0
aqc = 1
bqc = 0
aqd = 0
bqd = 1
aqr = 0
bqr = 0
res = 0
temp = 0
fin_hcf = 0
fin_lcd = 0
seq = []
inp = input('Please enter the first number, "a":\n')
a = inp
inp = input('Please enter the second number, "b":\n')
b = inp
mul = a * b # Will come in handy later!
if a < b:
print 'As you have entered the first number as smaller than the second, the program will swap a and b before proceeding.'
temp = a
a = b
b = temp
else:
print 'As the inputted value a is larger than or equal to b, the program has not swapped the values a and b.'
print 'Thank you. The program will now compute the HCF and simultaneously demonstrate Bezout\'s Lemma.'
print `a`+' = ('+`aqc`+' x '+`a`+') + ('+`bqc`+' x '+`b`+').'
print `b`+' = ('+`aqd`+' x '+`a`+') + ('+`bqd`+' x '+`b`+').'
seq.append(a)
seq.append(b)
c = a
d = b
while r != 0:
if s != 1:
c = seq[s-1]
d = seq[s]
res = divmod(c,d)
q = res[0]
r = res[1]
aqr = aqc - (q * aqd)#These two lines are the main part of the justification
bqr = bqc - (q * aqd)#-/
print `r`+' = ('+`aqr`+' x '+`a`+') + ('+`bqr`+' x '+`b`+').'
aqd = aqr
bqd = bqr
aqc = aqd
bqc = bqd
s = s + 1
seq.append(r)
fin_hcf = seq[-2] # Finally, the HCF.
fin_lcd = mul / fin_hcf
print 'Using Euclid\'s Algorithm, we have now found the HCF of '+`a`+' and '+`b`+': it is '+`fin_hcf`+'.'
print 'We can now also find the LCD (LCM) of '+`a`+' and '+`b`+' using the following method:'
print `a`+' x '+`b`+' = '+`mul`+';'
print `mul`+' / '+`fin_hcf`+' (the HCF) = '+`fin_lcd`+'.'
print 'So, to conclude, the HCF of '+`a`+' and '+`b`+' is '+`fin_hcf`+' and the LCD (LCM) of '+`a`+' and '+`b`+' is '+`fin_lcd`+'.'
I would greatly appreciate it if you could help me to find out what is going wrong with this.
Hmm, your program is rather verbose and hence hard to read. For example, you don't need to initialise lots of those variables in the first few lines. And there is no need to assign to the inp variable and then copy that into a and then b. And you don't use the seq list or the s variable at all.
Anyway that's not the problem. There are two bugs. I think that if you had compared the printed intermediate answers to a hand-worked example you should have found the problems.
The first problem is that you have a typo in the second line here:
aqr = aqc - (q * aqd)#These two lines are the main part of the justification
bqr = bqc - (q * aqd)#-/
in the second line, aqd should be bqd
The second problem is that in this bit of code
aqd = aqr
bqd = bqr
aqc = aqd
bqc = bqd
you make aqd be aqr and then aqc be aqd. So aqc and aqd end up the same. Whereas you actually want the assignments in the other order:
aqc = aqd
bqc = bqd
aqd = aqr
bqd = bqr
Then the code works. But I would prefer to see it written more like this which is I think a lot clearer. I have left out the prints but I'm sure you can add them back:
a = input('Please enter the first number, "a":\n')
b = input('Please enter the second number, "b":\n')
if a < b:
a,b = b,a
r1,r2 = a,b
s1,s2 = 1,0
t1,t2 = 0,1
while r2 > 0:
q,r = divmod(r1,r2)
r1,r2 = r2,r
s1,s2 = s2,s1 - q * s2
t1,t2 = t2,t1 - q * t2
print r1,s1,t1
Finally, it might be worth looking at a recursive version which expresses the structure of the solution even more clearly, I think.
Hope this helps.
Here is a simple version of Bezout's identity; given a and b, it returns x, y, and g = gcd(a, b):
function bezout(a, b)
if b == 0
return 1, 0, a
else
q, r := divide(a, b)
x, y, g := bezout(b, r)
return y, x - q * y, g
The divide function returns both the quotient and remainder.
The python program that does what you want (please note that extended Euclid algorithm gives only one pair of Bezout coefficients) might be:
import sys
def egcd(a, b):
if a == 0:
return (b, 0, 1)
g, y, x = egcd(b % a, a)
return (g, x - (b // a) * y, y)
def main():
if len(sys.argv) != 3:
's program caluclates LCF, LCM and Bezout identity of two integers
usage %s a b''' % (sys.argv[0], sys.argv[0])
sys.exit(1)
a = int(sys.argv[1])
b = int(sys.argv[2])
g, x, y = egcd(a, b)
print 'HCF =', g
print 'LCM =', a*b/g
print 'Bezout identity: %i * (%i) + %i * (%i) = %i' % (a, x, b, y, g)
main()

Categories

Resources