I'm getting a "mul object is not callable"-error - python

import sympy as sp
def taylorCoefficient(f, a, n):
x = sp.symbols("x")
coefficient = []
for i in range(0, n + 1):
afgeleide = sp.diff(f(x), x, n=n)
def f(x0): return afgeleide.subs(x, x0)
coefficient += f(a) / sp.factorial(n)
return coefficient
x = sp.symbols("x")
taylorCoefficient(x ** 2 * sp.sin(x / 2), 0, 3)
I'm getting a mul object is not callable, but why? (On line afgeleide=...)

Try changing the last line of your script to taylorCoefficient( lambda x: x**2*sp.sin(x/2), 0, 3).

Related

How to carry over variables from past defined functions?

I am writing a program that operates out of a main() function. I am unable to change the main function (this is part of a class). How would I go about carrying over a variable from one function to the next, without changing the main()?
def read_data(fname) :
file = fname
x = []
y = []
with open(file) as f:
for line in f:
xi, yi = [float(x) for x in line.split(",")]
x.append(xi)
y.append(yi)
return x, y
def compute_m_and_b(x, y) :
sx, sy, sx2, sxy, sy2 = 0, 0, 0, 0, 0
for i in range(len(x)):
sx += x[i]
sy += y[i]
sx2 += (x[i] ** 2)
sy2 += (y[i] ** 2)
sxy += (x[i] * y[i])
m = (sxy * len(x) - sx * sy) / (sx2 * len(x) - sx**2)
b = (sy - m * sx) / len(x)
return m, b
def compute_fx_residual(x, y, m, b) :
fx = []
for xi in x:
fx.append(m * xi + b)
residual = []
for i in range(len(y)):
residual.append(y[i] - fx[i])
return fx, residual
def compute_sum_of_squared_residuals(residual) :
least_squares_r = 0
for i in range(len(y)) :
least_squares_r += (residual[i]) ** 2
return least_squares_r
def compute_total_sum_of_squares(y) :
sum_squares = 0
ymean = sum(y) / len(y)
for i in range(len(y)) :
sum_squares += (yi - ymean) ** 2
return sum_squares
as you can see, I am restricted to only pulling the variables listed in the parentheses of the def functions. This leads to variables calculated in prior functions being undefined. How can I import them without needing to change the main()?
Please let me know if I should be more clear. I can provide more examples, but I wanted to maintain some brevity.
EDIT: here is the main function:
def main():
fname = input("Enter Input Filename: ")
x, y = regress.read_data(fname)
print()
print("Input File: ", fname)
print("Data points: ", len(x))
#compute coefficients m and b
m, b = regress.compute_m_and_b(x, y)
#compute fx and residual
fx, residual = regress.compute_fx_residual(x, y, m, b)
#compute sum of squared residuals
least_squares_r = regress.compute_sum_of_squared_residuals(residual)
#compute sum of squares
sum_squares = regress.compute_total_sum_of_squares(y)
#compute coefficeint of determination
coeff_of_d = regress.compute_coeff_of_determination(least_squares_r, sum_squares)
regress.print_least_squares(x, y, m, b, fx, residual, least_squares_r, sum_squares, coeff_of_d)
#compute pearson coefficient
pearson_r = regress.compute_pearson_coefficient(x, y)
regress.print_pearson(pearson_r)
return
main()
You haven't provided the main function so it's unclear how you're currently using it.
Looks to me like you can just get the variable for each consecutive function and pass them into the next:
fname = "some/path/to/file.txt"
x, y = read_data(fname)
m, b = compute_m_and_b(x, y, m, b)
fx, residual = compute_fx_residual(x, y, m, b)
least_squares_r = compute_sum_of_squared_residuals(residual)
sum_squares = compute_total_sum_of_squares(y)

Inefficient algorithm! Can you help me make this more efficient?

In mathematics, a Diophantine equation is a polynomial equation, usually with two or more unknowns, such that only the integer solutions are sought or studied.
This is the equation:
x**2 - 4 * y**2 = n
(where the unknowns are x and y, and n is a given positive number.
My function iterates through every value between 0-n. This is inefficient and can't always hack big n numbers. What is the best way to get the first unknown variable?
def sol_equa(n):
answers = []
for x in range(1 , n+1):
y = ((x ** 2 - n) / 4) ** (1 / 2)
try:
if y == y // 1:
answers.append([x, int(y)])
except TypeError:
continue
if len(answers) >= 1:
answers = list(reversed(answers))
return answers
else:
return []
sol_equation(90005) --> "[[45003, 22501], [9003, 4499], [981, 467], [309, 37]]"
You can use sympy.solvers.diophantine. Take your equation as
from sympy.solvers.diophantine import diophantine
from sympy.abc import x,y
n = 90005
solutions = diophantine(x**2 - 4*y**2 - n)
print(solutions)
#{(-981, 467), (-309, 37), (45003, 22501), (-45003, -22501), (309, -37), (-9003, -4499), (981, 467), (9003, -4499), (-9003, 4499), (45003, -22501), (309, 37), (-309, -37), (-45003, 22501), (9003, 4499), (981, -467), (-981, -467)}
If you want positive solutions only, you can use set comprehension:
positive_solutions = {sol for sol in solutions if sol[0] > 0 and sol[1] > 0}
print(positive_solutions)
#{(981, 467), (9003, 4499), (309, 37), (45003, 22501)}
Execution time tests
from timeit import timeit
sol_equa= '''
def sol_equa(n):
answers = []
for x in range(1 , n+1):
y = ((x ** 2 - n) / 4) ** (1 / 2)
try:
if y == y // 1:
answers.append([x, int(y)])
except TypeError:
continue
if len(answers) >= 1:
answers = list(reversed(answers))
return answers
else:
return []
sol_equa(90005)
'''
sympy_solver = '''
def sympy_solver(n):
solutions = diophantine(x**2 - 4*y**2 - n)
return {sol for sol in solutions if sol[0] > 0 and sol[1] > 0}
sympy_solver(90005)
'''
setup = '''
from sympy.solvers.diophantine import diophantine
from sympy.abc import x,y
'''
print(timeit(sympy_solver,number=1000, setup = setup))
#13.50360608200208
print(timeit(sol_equa,number=1000))
#I don't know, it took too long :P

Minimize system of nonlinear equation (integral on exponent)

General:
I am using maximum entropy to find distribution for on positive integers vectors, I can estimate the mean and variance, and have three equation I am trying to find a and b,
The equations:
integral(exp(a*x^2+bx+c) from (0 , infinity))-1
integral(xexp(ax^2+bx+c)from (0 , infinity))- mean
integral(x^2*exp(a*x^2+bx+c) from (0 , infinity))- mean^2 - var
(integrals between [0,∞))
The problem:
I am trying to use numerical solver and I used fsolve of sympy
But I guess I am missing some knowledge.
My code:
import numpy as np
import sympy as sym
from scipy.optimize import *
def myFunction(x,*data):
y = sym.symbols('y')
m,v=data
F = [0]*3
x[0] = - abs(x[0])
print(x)
F[0] = (sym.integrate(sym.exp(x[0] * y ** 2 + x[1] * y + x[2]), (y, 0,sym.oo)) -1).evalf()
F[1] = (sym.integrate(y*sym.exp(x[0] * y ** 2 + x[1] * y + x[2]), (y, 0,sym.oo))-m).evalf()
F[2] = (sym.integrate((y**2)*sym.exp(x[0] * y ** 2 + x[1] * y + x[2]), (y,0,sym.oo)) -v-m).evalf()
print(F)
return F
data = (10,3.5) # mean and var for example
xGuess = [1, 1, 1]
z = fsolve(myFunction,xGuess,args = data)
print(z)
my result are not that accurate, is there a better way to solve it?
integral(exp(a*x^2+bx+c))-1 = 5.67659292676884
integral(xexp(ax^2+bx+c))- mean = −1.32123173796713
integral(x^2*exp(a*x^2+bx+c))- mean^2 - var = −2.20825624606312
Thanks
I have rewritten the problem replacing sympy with numpy and lambdas (inline functions).
Also note that in your problem statement you subtract the third equation with $mean^2$, but in your code you only subtract $mean$.
import numpy as np
from scipy.optimize import minimize
from scipy.integrate import quad
def myFunction(x,data):
m,v=data
F = np.zeros(3) # use numpy array
# use scipy.integrade.quad for integration of lambda functions
# quad output is (result, error), so we just select the result value at the end
F[0] = quad(lambda y: np.exp(x[0] * y ** 2 + x[1] * y + x[2]), 0, np.inf)[0] -1
F[1] = quad(lambda y: y*np.exp(x[0] * y ** 2 + x[1] * y + x[2]), 0, np.inf)[0] -m
F[2] = quad(lambda y: (y**2)*np.exp(x[0] * y ** 2 + x[1] * y + x[2]), 0, np.inf)[0] -v-m**2
# minimize the squared error
return np.sum(F**2)
data = (10,3.5) # mean and var for example
xGuess = [-1, 1, 1]
z = minimize(lambda x: myFunction(x, data), x0=xGuess,
bounds=((None, 0), (None, None), (None, None))) # use bounds for negative first coefficient
print(z)
# x: array([-0.99899311, 2.18819689, 1.85313181])
Does this seem more reasonable?

Integrate a function by the trapezoidal rule- Python

Here is the homework assignment I'm trying to solve:
A further improvement of the approximate integration method from the last question is to divide the area under the f(x) curve into n equally-spaced trapezoids.
Based on this idea, the following formula can be derived for approximating the integral:
!(https://www.dropbox.com/s/q84mx8r5ml1q7n1/Screenshot%202017-10-01%2016.09.32.png?dl=0)!
where h is the width of the trapezoids, h=(b−a)/n, and xi=a+ih,i∈0,...,n, are the coordinates of the sides of the trapezoids. The figure above visualizes the idea of the trapezoidal rule.
Implement this formula in a Python function trapezint( f,a,b,n ). You may need to check and see if b > a, otherwise you may need to swap the variables.
For instance, the result of trapezint( math.sin,0,0.5*math.pi,10 ) should be 0.9979 (with some numerical error). The result of trapezint( abs,-1,1,10 ) should be 2.0
This is my code but It doesn't seem to return the right values.
For print ((trapezint( math.sin,0,0.5*math.pi,10)))
I get 0.012286334153465965, when I am suppose to get 0.9979
For print (trapezint(abs, -1, 1, 10))
I get 0.18000000000000002, when I am suppose to get 1.0.
import math
def trapezint(f,a,b,n):
g = 0
if b>a:
h = (b-a)/float(n)
for i in range (0,n):
k = 0.5*h*(f(a+i*h) + f(a + (i+1)*h))
g = g + k
return g
else:
a,b=b,a
h = (b-a)/float(n)
for i in range(0,n):
k = 0.5*h*(f(a + i*h) + f(a + (i + 1)*h))
g = g + k
return g
print ((trapezint( math.sin,0,0.5*math.pi,10)))
print (trapezint(abs, -1, 1, 10))
Essentially, your return g statement was indented, when it should not have been.
Also, I removed your duplicated code, so it would adhere to "DRY" "Don't Repeat Yourself" principle, which prevents errors, and keeps code simplified and more readable.
import math
def trapezint(f, a, b, n):
g = 0
if b > a:
h = (b-a)/float(n)
else:
h = (a-b)/float(n)
for i in range (0, n):
k = 0.5 * h * ( f(a + i*h) + f(a + (i+1)*h) )
g = g + k
return g
print ( trapezint( math.sin, 0, 0.5*math.pi, 10) )
print ( trapezint(abs, -1, 1, 10) )
0.9979429863543573
1.0000000000000002
This variation reduces the complexity of branches and reduces number of operations. The summation in last step is reduced to single operation on an array.
from math import pi, sin
def trapezoid(f, a, b, n):
if b < a:
a,b = b, a
h = (b - a)/float(n)
g = [(0.5 * h * (f(a + (i * h)) + f(a + ((i + 1) * h)))) for i in range(0, n)]
return sum(g)
assert trapezoid(sin, 0, 0.5*pi, 10) == 0.9979429863543573
assert trapezoid(abs, -1, 1, 10) == 1.0000000000000002

Numpy arange error with Lagrange Multiplier in Python

I try to use Lagrange multiplier to optimize a function, and I am trying to loop through the function to get a list of number, however I got the error
ValueError: setting an array element with a sequence.
Here is my code, where do I go wrong? If the n is not an array I can get the result correctly though
import numpy as np
from scipy.optimize import fsolve
n = np.arange(10000,100000,10000)
def func(X):
x = X[0]
y = X[1]
L = X[2]
return (x + y + L * (x**2 + y**2 - n))
def dfunc(X):
dLambda = np.zeros(len(X))
h = 1e-3
for i in range(len(X)):
dX = np.zeros(len(X))
dX[i] = h
dLambda[i] = (func(X+dX)-func(X-dX))/(2*h);
return dLambda
X1 = fsolve(dfunc, [1, 1, 0])
print (X1)
Helps would be appreciated, thank you very much
First, check func = fsolve()
Second, print(func([1,1,0]))` - result in not number ([2 2 2 2 2 2 2 2 2]), beause "n" is list. if you want to iterate n try:
import numpy as np
from scipy.optimize import fsolve
n = np.arange(10000,100000,10000)
def func(X,n):
x = X[0]
y = X[1]
L = X[2]
return (x + y + L * (x**2 + y**2 - n))
def dfunc(X,n):
dLambda = np.zeros(len(X))
h = 1e-3
r = 0
for i in range(len(X)):
dX = np.zeros(len(X))
dX[i] = h
dLambda[i] = (func(X+dX,n)-func(X-dX,n))/(2*h)
return dLambda
for iter_n in n:
print("for n = {0} dfunc = {1}".format(iter_n,dfunc([0.8,0.4,0.3],iter_n)))

Categories

Resources