Theano subtraction when you can't tile - theano

Say we have a theano matrix X that is nxm, and another one u that is nx1. We want to do X-u, but if we do that we'll get an input dimension mismatch. We could try tiling u, but tile only accepts constants and not variables. How do we do this?
import theano
import theano.tensor as T
X, u = T.dmatrices("X", "u")
T.addbroadcast(u, 1)
r = X - u
f = theano.function([X, u], r)
f([[1], [0]], [[1]])
I then get the error ('Bad input argument to theano function with name "<stdin>:1" at index 0(0-based)', 'Wrong number of dimensions: expected 2, got 1 with shape (2,).')

X - u should work exactly as you write it by broadcasting:
import theano
import theano.tensor as T
n = 10
m = 20
X = T.arange(n * m).reshape((n, m))
u = T.arange(0, n * m, m).reshape((n, 1))
r = X - u
r.eval()
Similar to your updated question, you can do
import theano
import theano.tensor as T
X = T.dmatrix()
u = T.addbroadcast(T.dmatrix(), 1)
r = X - u
f = theano.function([X, u], r)
XX = np.arange(20.).reshape(2, 10)
uu = np.array([1., 100.]).reshape(2, 1)
f(XX, uu)

Related

Translating a mixed-integer programming formulation to Scipy

I would like to solve the above formulation in Scipy and solve it using milp(). For a given graph (V, E), f_ij and x_ij are the decision variables. f_ij is the flow from i to j (it can be continuous). x_ij is the number of vehicles from i to j. p is the price. X is the available number vehicles in a region. c is the capacity.
I have difficulty in translating the formulation to Scipy milp code. I would appreciate it if anyone could give me some pointers.
What I have done:
The code for equation (1):
f_obj = [p[i] for i in Edge]
x_obj = [0]*len(Edge)
obj = f_obj + v_obj
Integrality:
f_cont = [0 for i in Edge] # continous
x_int = [1]*len(Edge) # integer
integrality = f_cont + x_int
Equation (2):
def constraints(self):
b = []
A = []
const = [0]*len(Edge) # for f_ij
for i in v: # for x_ij
for e in Edge:
if e[0] == i:
const.append(1)
else:
const.append(0)
A.append(const)
b.append(self.accInit[i])
const = [0]*len(Edge) # for f_ij
return A, b
Equation (4):
[(0, demand[e]) for e in Edge]
I'm going to do some wild guessing, given how much you've left open to interpretation. Let's assume that
this is a maximisation problem, since the minimisation problem is trivial
Expression (1) is actually the maximisation objective function, though you failed to write it as such
p and d are floating-point vectors
X is an integer vector
c is a floating-point scalar
the graph edges, since you haven't described them at all, do not matter for problem setup
The variable names are not well-chosen and hide what they actually contain. I demonstrate potential replacements.
import numpy as np
from numpy.random._generator import Generator
from scipy.optimize import milp, Bounds, LinearConstraint
import scipy.sparse
from numpy.random import default_rng
rand: Generator = default_rng(seed=0)
N = 20
price = rand.uniform(low=0, high=10, size=N) # p
demand = rand.uniform(low=0, high=10, size=N) # d
availability = rand.integers(low=0, high=10, size=N) # X aka. accInit
capacity = rand.uniform(low=0, high=10) # c
c = np.zeros(2*N) # f and x
c[:N] = -price # (1) f maximized with coefficients of 'p'
# x not optimized
CONTINUOUS = 0
INTEGER = 1
integrality = np.empty_like(c, dtype=int)
integrality[:N] = CONTINUOUS # f
integrality[N:] = INTEGER # x
upper = np.empty_like(c)
upper[:N] = demand # (4) f
upper[N:] = availability # (2) x
eye_N = scipy.sparse.eye(N)
A = scipy.sparse.hstack((-eye_N, capacity*eye_N)) # (3) 0 <= -f + cx
result = milp(
c=c, integrality=integrality,
bounds=Bounds(lb=np.zeros_like(c), ub=upper),
constraints=LinearConstraint(lb=np.zeros(N), A=A),
)
print(result.message)
flow = result.x[:N]
vehicles = result.x[N:].astype(int)

How to solve for Hyperbola in python

I am trying to solve the hyperbolic equation in the following way to find x and y. I wanted to know if it made sense to use the same equation twice in fsolve to find first x and then y. My code is as follows:
from scipy.optimize import *
from numpy import *
import math
a = 1/(a_6**2)
b = 1/(b_6**2)
def function_hyper(loc):
x = loc[0]
y = loc[1]
F = empty((2))
F[0] = a*pow(x, 2) - b*pow(y, 2) - 1
F[1] = a*pow(x, 2) - b*pow(y, 2) - 1
return F1
loc_Guess = np.array([0.0141, 0.107])
location = fsolve(function_hyper, loc_Guess)
Here, a_6 and b_6 are variables calculated from previous steps. a and b are co-efficients for solving hyperbolic equation of x^2/a^2 - y^2/b^2 = 1. This is the equation I have written in F[0] and F[1]. empty is to define F before using it. So after having values for F, empty gets replaced. pow is to define a power of 2 for squaring x and y.
According to the documentation, fsolve is just a Wrapper around MINPACK's hybrd routine:
The purpose of HYBRD is to find a zero of a system of N non-linear functions in N variables by a modification of the Powell hybrid method. The user must provide a subroutine which calculates the functions. The Jacobian is then calculated by a forward-difference approximation.
Consequently, you need N equations to find the root of a function in N variables. Hence, in case one wants to find the root of a function f: R^N -> R one could either solve the system of N equations (f(x), ..., f(x)) = (0, ..., 0) (like you did) or simply (f(x), 0, ..., 0) = (0, ..., 0). The latter looks like this in code:
import numpy as np
a = 1/(a_6**2)
b = 1/(b_6**2)
def function_hyper(loc):
x, y = loc[0], loc[1]
F = np.zeros(2)
F[0] = a * x**2 - b * y**2 - 1
return F

DOcplexException: Expression xx cannot be used as divider of xxx

I am new to CPLEX and I was trying to find an example where the decision variable is in the denominator of the objective function but couldn't. My optimisation problem;
I have tried the following on Python3;
from docplex.mp.model import Model
import numpy as np
N = 1000
S = 10
k = 2
u_i = np.random.rand(N)[:,np.newaxis]
u_ij = np.random.rand(N*S).reshape(N, S)
beta = np.random.rand(N)[:,np.newaxis]
m = Model(name = 'model')
R = range(1, S+1)
idx = [(j) for j in R]
I = m.binary_var_dict(idx)
m.add_constraint(m.sum(I[j] for j in R)<= k)
total_rev = m.sum(beta[i,0] / ( 1 + u_i[i,0]/sum(I[j] * u_ij[j,i-1] for j in R) ) for i in range(N) )
m.maximize(total_rev)
sol = m.solve()
sol.display()
However Im getting the following error when running the line;
total_rev = m.sum(beta[i,0] / ( 1 + u_i[i,0]/sum(I[j] * u_ij[j,i-1] for j in R) ) for i in range(N) )
Error :
DOcplexException: Expression 0.564x1+0.057x2+0.342x3+0.835x4+0.452x5+0.802x6+0.324x7+0.763x8+0.264x9+0.226x10 cannot be used as divider of 0.17966220449798675
Can you please help me to overcome this error?
Since your objective is not linear you should use CPO within CPLEX
from docplex.cp.model import CpoModel
import numpy as np
N = 10
S = 10
k = 2
u_i = np.random.rand(N)[:,np.newaxis]
u_ij = np.random.rand(N*S).reshape(N, S)
beta = np.random.rand(N)[:,np.newaxis]
m = CpoModel(name = 'model')
R = range(1, S)
idx = [(j) for j in R]
I = m.binary_var_dict(idx)
m.add_constraint(m.sum(I[j] for j in R)<= k)
total_rev = m.sum(beta[i,0] / ( 1 + u_i[i,0]/sum(I[j] * u_ij[j,i-1] for j in R) ) for i in range(N) )
m.maximize(total_rev)
sol=m.solve()
for i in R:
print(sol[I[i]])
works fine

My differential equation solver not solving the differential equation

I'm trying to solve ODE using euler method 1 (https://en.wikipedia.org/wiki/Euler_method). But my code isn't solving anything. The code is very similar to my teacher, to the point that I can't find any significant difference. Can anybody help?
enter from math import *
import numpy as np
import matplotlib.pyplot as plt
def funkce(y, t):
return(-y)
def euler_1(dt, y, t, funkce ):
y = y + dt * funkce(y, t)
t = t + dt
return (y,t)
def solver(y0, t0, tstop, dt, typ):
y = y0
t = t0
ys = [y]
ts = [t]
while (t < tstop):
(y,t) = typ(dt, y, t, funkce)
ts.append(t)
ys.append(y)
return(ys,ts)
plt.plot(solver(1, 0, 50, 0.05, euler_1))
t = np.linspace(0, 5, 50)
y = np.exp(-t)
plt.plot(t, y)
plt.show()
Note: the last plot is to compare to the analytical solution.
You can find the plot output here.
When I retun from solver y and t instead of ys,ts it just show the last line of ys and ts.
Any help apreciated.

Sympy - Float has no attribute sqrt

I am working on a code snippet, where I am unable to debug the issue, any suggestions would be appreciated.
The error is attribute error: Float object has no attribute sqrt
from sympy import *
import numpy as np
rho_l = 1000;
rho_g= 1.225;
sigma = 0.072
nu = 0.001;
Q = rho_g/ rho_l;
u = 14.8;
k = Symbol('k', real=True)
w1 = -2*nu*k**2
w2 = 4* (nu**2) * (k**4);
w3 = - Q* (u**2) * (k**2);
w4 = - sigma * (k**3)/ rho_l;
w = w1 + sqrt(w2+w3+w4);
print (w)
wprime = w.diff(k)
print (wprime)
ko = solve(wprime, k) # solve fprime = 0 with respect to x
ko = ko[0]
print (ko)
ws = lambdify (k, w, 'numpy');
print (type(ko))
print (ws(ko))
You're getting that error because numpy apparently doesn't know how to handle sympy.core.numbers.Float types (https://docs.sympy.org/latest/modules/core.html#sympy.core.numbers.Float). Therefore, the numpy sqrt raises the exception when you call ws. To fix, pass sympy to lambdify instead of numpy.
ws = lambdify (k, w, 'sympy');
print (type(ko)) # >> <class 'sympy.core.numbers.Float'>
print (ws(ko)) # >> -82.5885350883393
Alternatively you could convert the sympy.Float to a regular float using float() and replace k0 by float(k0) .
ws = lambdify(k, w, 'numpy');
print(type(float(ko))) # >> <class 'float'>
print(ws(float(ko))) # >> -82.58853508833931

Resources