Python fmin(find minimum) for a vector function - python

I would like to find the minimum of 3dvar function defined as:
J(x)=(x-x_b)B^{-1}(x-x_b)^T + (y-H(x)) R^{-1} (y-H(x))^T (latex code)
with B,H,R,x_b,y given.
I would like to find the argmin(J(x)). However it seems fmin in python does not work. (the function J works correctly)
Here is my code:
import numpy as np
from scipy.optimize import fmin
import math
def dvar_3(x):
B=np.eye(5)
H=np.ones((3,5))
R=np.eye(3)
xb=np.ones(5)
Y=np.ones(3)
Y.shape=(Y.size,1)
xb.shape=(xb.size,1)
value=np.dot(np.dot(np.transpose(x-xb),(np.linalg.inv(B))),(x-xb)) +np.dot(np.dot(np.transpose(Y-np.dot(H,x)),(np.linalg.inv(R))),(Y-np.dot(H,x)))
return value[0][0]
ini=np.ones(5) #
ini.shape=(ini.size,1) #change initial to vertical vector
fmin(dvar_3,ini) #start at initial vector
I receive this error:
ValueError: operands could not be broadcast together with shapes (5,5) (3,3)
How can I solve this problem? Thank you in advance.

reshape argument x in the function dvar_3, the init argument of fmin() needs a one-dim array.
import numpy as np
from scipy.optimize import fmin
import math
def dvar_3(x):
x = x[:, None]
B=np.eye(5)
H=np.ones((3,5))
R=np.eye(3)
xb=np.ones(5)
Y=np.ones(3)
Y.shape=(Y.size,1)
xb.shape=(xb.size,1)
value=np.dot(np.dot(np.transpose(x-xb),(np.linalg.inv(B))),(x-xb)) +np.dot(np.dot(np.transpose(Y-np.dot(H,x)),(np.linalg.inv(R))),(Y-np.dot(H,x)))
return value[0][0]
ini=np.ones(5) #
fmin(dvar_3,ini) #start at initial vector

Related

How to integrate bivariate normal using quadpy

I am trying to use quadpy to integrate a function against the bivariate normal dist. To test it is working, I tried
from scipy.stats import multivariate_normal
import numpy as np
import quadpy
rho = 0.95
cov = np.array([[1, rho], [rho, 1]])
bivn = multivariate_normal(mean=None, cov=cov)
pdfer2 = lambda x: bivn.pdf(np.stack(x,axis=1))*np.exp(x[0]**2 + x[1]**2)
scheme = quadpy.e2r2.get_good_scheme(3)
val = scheme.integrate(pdfer2)
The result I get is val=1.25, which is quite far from 1. If I remove the np.stack, I get an error:
File "C:\Users\steve\anaconda3\lib\site-packages\scipy\stats_multivariate.py", line 473, in _logpdf
dev = x - mean
ValueError: operands could not be broadcast together with shapes (2,6) (2,)
Any idea what I am doing wrong? Or is this level of error expected? Is there an error estimate available? (integrate just seems to return a single value).
Thanks!

How could the energy and cos function be in different shapes?

I am trying to write a code that calculates an integral from zero to pi. But it gives an error which I do not understand how to fix. Thank you for your time.
import numpy as np
from math import pi,cos
vtheta=np.linspace(0.0,pi,1000)
def my_function(x):
Energy = np.arange(2.1,300.1,0.1)
return ((1.0)/(Energy-1+np.cos(x)))
print (my_function(vtheta).sum())
As is pointed out in the top comment:
Energy.shape == (2980,), but x.shape == (1000,)
so reduce the number of elements in Energy or increase np.cos(x).
Since energy is just a numpy arrage i reduced it to size=1000.
In order to fix this they need to be the same size, so this ,for example, works:
import numpy as np
from math import pi,cos
vtheta=np.linspace(0.0,pi,1000)
def my_function(x):
Energy = np.arange(2.1,102.1,0.1) #<-- changed 300.1 to 102.1
return ((1.0)/(Energy-1+np.cos(x)))
print (my_function(vtheta).sum())
This is the result (with the above):
39.39900748229355

How to calculate improper integral in python?

How can I calculate the value of this integral:
f_tu(t) is given as numpy.array. The graph looks like this:
How can I implement this?
Everything I could find looks something like this
from scipy.integrate import quad
def f(x):
return 1/sin(x)
I = quad(f, 0, 1)
but I have an array there, not a specific function like sin.
How about auc from sklearn.metrics?
import numpy as np
import numpy as np
from scipy.integrate import quad
from sklearn.metrics import auc
x = np.arange(0, 100, 0.001)
y = np.sin(x)
print('auc:', auc(x,y))
print('quad:', quad(np.sin, 0, 100))
auc: 0.13818791291277366
quad: (0.1376811277123232, 9.459751315610276e-09)
Okay, so you have one of those pesky infinity integrals. Here is how I would deal with it:
import numpy as np
from scipy.integrate import quad
def f(x):
return(1/(x**2)) #put your function to integrate here
print(quad(f,0,np.Infinity)) #integrates from 0 to infinity
This returns two values. The first is the estimated value of the integral, and the second is the approximate absolute error of the integral which is useful to know.
If you want to integrate a numpy array here is a simple solution:
import numpy as np
print(np.trapz(your numpy array here))

python: Plotting and optimizing the same function

Lets say I have the following function:
def f(x):
return log(3*exp(3*x) + 7*exp(7*x))
I want to do two things:
1) plot the function over a range of x-values
2) find the root of the function using the Newton method from scipy
My problem is that it seems that plotting is best done with a numpy array x=np.linspace(-2,2,1000), but then evaluating the function results in erros TypeError: only size-1 arrays can be converted to Python scalars. I can fix this by simply changing log and exp to np.log and np.exp, respectively.
But doing so then makes scipy.optimize.newton unhappy.
It seems like I need to define the function twice, once for use in plotting (with np. ...) and once for optimizing in the form given above.
I can't imagine that this is actually the case. Any hints would be greatly appreciated.
Seems legit, you just need to use numpy functions instead of base math functions:
import numpy as np
from scipy import optimize
import matplotlib.pyplot as plt
%matplotlib inline
def f(x):
return np.log(3*np.exp(3*x) + 7*np.exp(7*x))
x = np.linspace(-2,2,1000)
y = f(x)
plt.scatter(x, y)
optimize.root(f, 1)

Runtime Return array size Error Python

I am trying to solve a simple differential equation using odeint function. It is giving an error with matching size of array. I think my initial_condi is not matching with the equation function. I can't figure it out where actually the error is. Blow is the error and code. Any help would be greatly appreciated.
RuntimeError: The size of the array returned by func (1) does not match the size of y0 (3)
from scipy import *
from scipy.integrate import odeint
from operator import itemgetter
import matplotlib as plt
from matplotlib.ticker import FormatStrFormatter
from pylab import *
from itertools import product
import itertools
from numpy import zeros_like
import operator
initial_condi = [1, 1, 1]
t_range = arange(0.0,60.0,1.0)
def equation(w, t):
T,I,V = w
dT= V*I*10.24-T*1.64
return dT
result_init = odeint(equation, initial_condi, t_range)
plt.plot(t, result_init[:, 0])
plt.show()
As your state vector has 3 components, the return value of the ODE function also needs to have 3 components, the derivatives of T,I,V. You only provided dT, but should return [dT, dI, dV ].

Categories

Resources