ValueError: setting an array element with a sequence please - python

My code is working right except when i enter r1 into the function equation below
def u(Substrate):
return((u_max*ys[:,0])/(Ks+ys[:,0]))
biomass = ys[:,1]
u = u(ys[:,0])
def r1(u,biomass):
r1 = u*biomass*YieldCO2_1
return r1
r1 = r1(u,biomass)
def F(y,t):
Ptot = 710
Vgas = 2
D = 0.00826*(273.15+Temp)
Cstar_CO2 = KH_CO2 * y[2]
Cstar_CH4 = KH_CH4 * y[3]
TG_CO2 = KLa_CO2*(Cstar_CO2-y[0])
TG_CH4 = KLa_CH4*(Cstar_CH4-y[1])
Q_CO2 = -D*V*TG_CO2
Q_CH4 = -D*V*TG_CH4
Qgas = (Q_CO2+Q_CH4)+Q
F=np.zeros(4)
F[0] = Q/V * (CO2_To-y[0]) + TG_CO2 + r1
F[1] = Q/V * (CH4_Do-y[1]) + TG_CH4
F[2] = -Ptot*D*TG_CO2*(V/Vgas)-y[2]*(Qgas/Vgas)
F[3] = -Ptot*D*TG_CH4*(V/Vgas)-y[3]*(Qgas/Vgas)
return F
yinit = np.array([4,3,250,200])
ts = np.arange(0,4,0.4)
y = odeint(F,yinit,ts)
When r1 is seen in equation F[0] I get the following error:
F[0] = Q/V * (CO2_To-y[0]) + TG_CO2 + r1
ValueError: setting an array element with a sequence.
odepack.error: Error occurred while calling the Python function named F
However when I do the function without the r1 array, there is no error. so that is why i am assuming something is wrong with putting the r1 array into the function
If anyone could provide input to my problem i would

F[0] = expression expects expression to be a number here, not an array. However Q/V * (CO2_To-y[0]) + TG_CO2 + r1 is an array of r1 dimensions. To see this, try evaluating the following line:
>>> 1 + numpy.array([1,2])
array([2, 3])
To get rid of the exception you should covert this expression to a number somehow depending on what you are trying to achieve.

Related

How do I get this tuple to compute with my function?

def heat_transfer(enter_temperature, leave_temperature, flow_rate) :
enter_temperature -= leave_temperature
temp_change = enter_temperature
C = 4.19
density = 1
Q = (flow_rate * density) * C * temp_change
return Q
historical_chiller_data = [(9.5, 6.300000191, 21.25596786, 34.75609756), (13.5, 6.900000095, 25.2404719, 53.28244275), (10.10000038, 7.699999809, 23.76689968, 19.91666667)]
def coefficient_performance_vs_heat_transfer(historical_data) :
x, y, z = historical_data
new_list = list(x)
new_list2 = new_list.pop()
heat_tranfer(new_list)
I know it's not complete but I am stuck trying to use the first three elements of the tuple in my function... Any suggestions??

How to perform Constrained Optimization by Jacobian like Matlab?

I have a code for doing constrained optimization in Matlab:
this one is for objective function from deriving a function according to the constraint and the case:
function f=funcobj(X);
f=[(2-3*X(1)*2+X(3)*(1-X(1))+X(4)*(5+X(1)/5));
(3-4*X(2)+3*X(3)+2*X(4));
(X(1)+3*X(2)-X(1).^2/2-5.5);
(5*X(1)+2*X(2)+X(1).^2/10-10)];
end
and this one is the Jacobian function
function [f0,jac]=jacobian(x);
h = 1.0e-4;
n = length(x);
jac = zeros(n,n);
f0 = funcobj(x);
for zz=1:n;
temp = x(zz);
x(zz)= temp + h;
f1 = funcobj(x);
x(zz)= temp;
jac(:,zz) = (f1 - f0)/h;
disp((f1 - f0)/h);
end
% disp(jac)
and this one is the main code
clc;close all;clear all
%initial
X(1,:)= [1 1 1 1]';
niter=30;tol=1e-6;
for ii=1:niter-1
disp(X(ii,:));
[f,dp]=jacobian(X(ii,:));
dX=inv(dp)*f;
X(ii+1,:)=X(ii, :)'-dX;
fprintf('Iterasion=ti Solution=$.4f \n',ii,X(ii+1))
if abs(X(ii+1,:)-X(ii,:))<tol;
r=X(ii+1,:);
disp('The Solution is convergent')
break
end
end
x=r(1);y=r(2);lambda_1=r(3);lambda_2=r(4);
f = (2*x)+(3*y)-(x).^3-2*(y.^2);
disp('Case 1')
disp(['x=' num2str(x) ', y = ' num2str(y),',f = ' num2str(f)])
disp(['lambda_1 = ' num2str(lambda_1), ', lambda_2 = ' num2str(lambda_2)])
When I try to convert it to Python, I still confused with the X array and how to rewrite jacobian in Python. This is my attempt:
import numpy as np
def funcobj(z):
f = np.array([[2-3*z[0]**2 + z[2]*(1-z[0])+z[3]*(5+z[0]/5)], [(-4*z[1]+3*z[2]+2*z[3])], [z[0]+3*z[1]-(z[2]**2)/2-5.5], [5*z[0]+2*z[1]+(z[0]**2)/10-10]])
print(f)
return f
def jacobian(X):
h = 1.0e-4
n = len(X)
print(n)
jac = np.zeros([4,4])
f0 = funcobj(X)
for i in range(0,n):
temp = X[i]
X[i] = temp + h
f1 = funcobj(X)
X[i] = temp
#print((f1-f0)/h)
jac[0,i] = (f1-f0)/h
return (f0, jac)
X=np.array([[1],[1],[1],[1]])
niter=30
tol=1e-6
for i in range(0,niter):
jacobian(X[:,i])
if abs(X[:,i]-X[:,i-1])<tol:
r=X[:,i]
print('The Solution is convergent')
break
How to fix this code? I still get the error in Python
Your funcobj returns a np.ndarray with shape (n,1) instead of (n,). Note that contrary to matlab, in numpy, the former corresponds to a matrix while the latter corresponds to a vector. Next, in the line jac[0, i] = (f1-f0)/h you are trying to assign a np.ndarray to a single matrix element. It should be jac[:, i] instead. Note also that range starts by default at 0 since python has 0-based indexing.
In code:
def funcobj(z):
f1 = 2-3*z[0]**2 + z[2]*(1-z[0])+z[3]*(5+z[0]/5)
f2 = (-4*z[1]+3*z[2]+2*z[3])
f3 = z[0]+3*z[1]-(z[2]**2)/2-5.5
f4 = 5*z[0]+2*z[1]+(z[0]**2)/10-10
return np.array((f1, f2, f3, f4))
def jacobian(X):
h = 1.0e-4
n = len(X)
jac = np.zeros([4,4])
f0 = funcobj(X)
for i in range(n):
temp = X[i]
X[i] = temp + h
f1 = funcobj(X)
X[i] = temp
#print((f1-f0)/h)
jac[:,i] = (f1-f0)/h
return (f0, jac)
x0 = np.ones(4)
# works as expected
print(jacobian(x0))
Now it's your turn to go on from here and implement the main algorithm in python.

Why do I get a type error when trying to change value of tkinter's entry boxes to numbers?

a = IntVar(root, aEntry.get())
b = IntVar(root, bEntry.get())
c = IntVar(root, cEntry.get())
y = a*x**2 + b*x + c
This gives me this error: "TypeError: unsupported operand type(s) for *: 'IntVar' and 'float'". If it helps, I am trying to use that equation to draw a quadratic graph using numpy and matplotlib.
You're multiplying the IntVar object itself, which is wrong.
Instead, you want to multiply the value that is stored inside the IntVar. Use .get() to fetch the value.
y = a.get() * x**2 + b.get() * x + c.get()
You don't need to use IntVar at all, just convert the content from those entries to integer:
try:
a = int(aEntry.get())
b = int(bEntry.get())
c = int(cEntry.get())
y = a * x**2 + b * x + c
except ValueError as ex:
print(ex)

Replacing Sympy indexed symbols with numeric values

I have a sympy expression I want to put numerical values in after differentiating it. The variables I want to replace are all the x[i], y[i] and R_abs[i] in the last expression and are numpy arrays a la
rx=np.array([-0.357, -0.742, -1.078, 0.206])
But trying subs or replace either doesn't do anything or raises the error that Symbols dont allow indexation for for example e1.subs(x[1],rx[0]). I pretty much went through every iteration I could think of to no avail.
import sympy as sp
r0,ge_x,ge_y,bx,by = sp.symbols('r0,ge_x,ge_y,bx,by', real=True) #Main symbols
i,x,y,R_abs = sp.symbols('i,x,y,R_abs', real=True) #Helper symbols
n=4
s2=sp.Sum((bx+r0*sp.Indexed('x',i)/sp.Indexed('R_abs',i)+ge_x*sp.Indexed('x',i)+ge_y*sp.Indexed('y',i)-sp.Indexed('x',i))**2+(by+r0*sp.Indexed('y',i)/sp.Indexed('R_abs',i)-ge_x*sp.Indexed('y',i)+ge_y*sp.Indexed('x',i)-sp.Indexed('y',i))**2,(i,1,n))
e1=sp.Eq(sp.diff(s2,bx).doit(),0)
With e1 then being
Eq(8*bx + 2*ge_x*x[1] + 2*ge_x*x[2] + 2*ge_x*x[3] + 2*ge_x*x[4] + 2*ge_y*y[1] + 2*ge_y*y[2] + 2*ge_y*y[3] + 2*ge_y*y[4] + 2*r0*x[4]/R_abs[4] + 2*r0*x[3]/R_abs[3] + 2*r0*x[2]/R_abs[2] + 2*r0*x[1]/R_abs[1] - 2*x[1] - 2*x[2] - 2*x[3] - 2*x[4], 0)
In here I would like to replace all the x, y, and R_abs with their numerical values.
I've always struggled with indexing in SymPy. Turns out, making Function instances are way easier than indexing instances of Symbol. It also makes notation simpler.
Also note that by using strings in your expression, I think SymPy makes its own symbols with those same string names but they can't be accessed with yours since your symbols are different. At least that's what happens sometimes to me.
Here is a working sample:
import sympy as sp
r0, ge_x, ge_y, bx, by = sp.symbols("r0 ge_x ge_y bx by", real=True) # main symbols
# define functions that will take the role of indexed symbols
x = sp.Function("x")
y = sp.Function("y")
R_abs = sp.Function("R_abs")
i = sp.Symbol("i", positive=True, integer=True)
n = 4
s2 = sp.Sum((bx + r0 * x(i) / R_abs(i) + ge_x * x(i) + ge_y * y(i) - x(i)) ** 2 +
(by + r0 * y(i) / R_abs(i) - ge_x * y(i) + ge_y * x(i) - y(i)) ** 2, (i, 1, n))
s2_prime = sp.diff(s2, bx).doit().simplify()
print(s2_prime)
# whatever lists you want. Can even be an instance of `np.ndarray`
# note that you summed from 1 to n so the 0th element will not be used
x_array = [0, 1, 2, 3, 4]
y_array = [4, 3, 2, 1, 0]
R_abs_array = [-10, 10, 5, 4, 3]
# define a function to access these array elements
x_function = lambda index: x_array[index]
y_function = lambda index: y_array[index]
R_abs_function = lambda index: R_abs_array[index]
# no idea why subs does not work and you MUST keep the same name for the variable.
# you can't have for example `evaluated_s2_prime = ...`.
# Probably something to do with forcing sp to remove references to `x`?
s2_prime = s2_prime.replace(x, x_function).replace(y, y_function).replace(R_abs, R_abs_function)
print(s2_prime)
Producing:
8*bx + 2*ge_x*x(1) + 2*ge_x*x(2) + 2*ge_x*x(3) + 2*ge_x*x(4) + 2*ge_y*y(1) + 2*ge_y*y(2) + 2*ge_y*y(3) + 2*ge_y*y(4) + 2*r0*x(4)/R_abs(4) + 2*r0*x(3)/R_abs(3) + 2*r0*x(2)/R_abs(2) + 2*r0*x(1)/R_abs(1) - 2*x(1) - 2*x(2) - 2*x(3) - 2*x(4)
8*bx + 20*ge_x + 12*ge_y + 31*r0/6 - 20

Python outputs parentheses

I'm sorta new to python, and I wanted to try to create a program that finds the slope of two inputted points. I assume I'm doing fine on the math part, but the output part is my problem. This is my code:
import math
x1 = input("x1 = ")
y1 = input("y1 = ")
x2 = input("x2 = ")
y2 = input("y2 = ")
chy = y2 - y1
chx = x2 - x1
slope = 'Slope = ', chy, '/', chx
print (slope)
and this is my expected output:
x1 = 1
y1 = 1
x2 = 2
y2 = 2
Slope = 1/1
and this is my ACTUAL output:
x1 = 1
y1 = 1
x2 = 2
y2 = 2
('Slope = ', 1, '/', 1)
any help?
Right now, slope is a tuple (a sequence of Python objects), which is not what you want. What you want to do is
slope = 'Slope = ' + str(chy) + "/"+ str(chx)
This uses string concatenation (every part is a string, it is all put together).
Alternatively, you can use string formatting.
slope = "Slope = {}/{}".format(chy,chx)
You want string concatenation:
slope = 'Slope = ' + str(chy) + '/' + str(chx)
The + operator is used in Python to concatenate strings. However, it will give an error if you don't convert chy and chx to strings (by using str()), since they currently have numerical values.
Another way to print strings is to use string formatting:
slope = 'Slope = {}/{}'.format(str(chy), str(chx))

Categories