I am pretty new to NumPy and jupyter. I wondered if we had a way to get the minima or maxima of an expression stored in a variable.
I have multiple functions stored in an array as a by-product of different computations.
Something like f = 3t**2 + 3t + 3
is just an example, I am actually getting way more complicated functions so manually doing it seems out of the question. This is one of the functions 6.34436761121718*sqrt((0.097474416000379*t + 0.0188371834173637*(0.494829394598486 - t)**2 - 1)**2 + 0.304869715505419*(0.097474416000379*t + 0.062337860997632*(0.441516112455913 - t)**2 - 1)**2 + 0.0416140775153019*(0.097474416000379*t + 0.114241389774407*(t + 0.958019398183372)**2 - 1)**2)
I tried fmin solution suggested by bitflip and I got an error.
TypeError Traceback (most recent call last)
Input In [41], in <cell line: 1>()
2 def f(t):
3 return sqrt(sum(map(lambda i : i * i, np.subtract(differenceInRSquare(i, j), divisionRandP(i, j)))))
----> 5 fmin(f, 0)
File ~\anaconda3\lib\site-packages\scipy\optimize\optimize.py:580, in fmin(func, x0, args, xtol, ftol, maxiter, maxfun, full_output, disp, retall, callback, initial_simplex)
471 """
472 Minimize a function using the downhill simplex algorithm.
473
(...)
570
571 """
572 opts = {'xatol': xtol,
573 'fatol': ftol,
574 'maxiter': maxiter,
(...)
577 'return_all': retall,
578 'initial_simplex': initial_simplex}
--> 580 res = _minimize_neldermead(func, x0, args, callback=callback, **opts)
581 if full_output:
582 retlist = res['x'], res['fun'], res['nit'], res['nfev'], res['status']
File ~\anaconda3\lib\site-packages\scipy\optimize\optimize.py:750, in _minimize_neldermead(func, x0, args, callback, maxiter, maxfev, disp, return_all, initial_simplex, xatol, fatol, adaptive, bounds, **unknown_options)
747 fsim = np.empty((N + 1,), float)
749 for k in range(N + 1):
--> 750 fsim[k] = func(sim[k])
752 ind = np.argsort(fsim)
753 fsim = np.take(fsim, ind, 0)
File ~\anaconda3\lib\site-packages\sympy\core\expr.py:345, in Expr.__float__(self)
343 if result.is_number and result.as_real_imag()[1]:
344 raise TypeError("Cannot convert complex to float")
--> 345 raise TypeError("Cannot convert expression to float")
TypeError: Cannot convert expression to float
This is my jupyter file.
#!/usr/bin/env python
# coding: utf-8
# In[1]:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
import random
import math
from sympy import *
from matplotlib import animation
from matplotlib.animation import PillowWriter
from itertools import combinations
from mpl_toolkits.mplot3d import Axes3D
from scipy.optimize import fmin
from scipy.optimize import minimize
# In[2]:
n_particles =6
r = np.random.random((3,n_particles))
v = np.random.random((3,n_particles))
# In[3]:
var=('t')
# In[4]:
r
# In[5]:
r.shape
# In[6]:
r
# In[10]:
P
# In[11]:
r@P.T
# In[12]:
ids = np.arange(n_particles)
# In[13]:
ids
# In[14]:
import sympy as smp
p, y,t,R,m = smp.symbols('p y t R m', real=True, positive=True)
fs = smp.exp(-smp.sqrt((p**2))/t)
fs
# In[15]:
Fmp=smp.integrate(fs,(p,0,y))
Fmp
# In[16]:
Ps=-smp.log(1-R*(1-smp.exp(-5)))
Ps
# In[17]:
R=np.random.random_sample(size = n_particles)
R
# In[18]:
absolute_momentum= np.array([[-np.log(1-i*(1-np.exp(-5))) for i in R]])
# In[19]:
absolute_momentum
# In[20]:
absolute_momentum.shape
# In[21]:
def polar_to_cart(r, theta, phi):
return [r * math.sin(theta) * math.cos(phi),r * math.sin(theta) * math.sin(phi),r * math.cos(theta)]
def px(r, theta, phi):
return (r * math.sin(theta) * math.cos(phi))
def py(r, theta, phi):
return (r * math.sin(theta) * math.sin(phi))
def pz(r, theta, phi):
return (r * math.cos(theta))
# In[22]:
theta=np.random.uniform(0,math.pi/2,[1,n_particles])
phi=np.random.uniform(0,math.pi/2,[1,n_particles])
phi.shape
# In[23]:
theta
# In[24]:
px_values=[px(i,j,k) for i,j,k in np.nditer([absolute_momentum,theta,phi]) ]
py_values=[py(i,j,k) for i,j,k in np.nditer([absolute_momentum,theta,phi]) ]
pz_values=[pz(i,j,k) for i,j,k in np.nditer([absolute_momentum,theta,phi]) ]
# In[25]:
px_values
# In[26]:
P = np.zeros((3,n_particles))
P[0]=px_values
P[1]=py_values
P[2]=pz_values
P
# In[27]:
py_values
# In[28]:
px_values/absolute_momentum
# In[29]:
py_values/absolute_momentum
# In[30]:
pz_values/absolute_momentum
# In[31]:
Ratio = P/absolute_momentum
Ratio
# In[32]:
R = r + Ratio*t
R
# In[33]:
ids_pairs = np.asarray(list(combinations(ids,2)))
ids_pairs
# In[34]:
def differenceInR(i, j):
return [(R[0][i] - R[0][j]), (R[1][i] - R[1][j]), (R[2][i] - R[2][j])]
# In[35]:
def differenceInRSquare(i, j):
return np.square(differenceInR(i, j))
# In[36]:
def sumOfP(i, j):
return [(P[0][i] + P[0][j]), (P[1][i] + P[1][j]), (P[2][i] + P[2][j])]
# Function to get product of difference of position and sum of momentum
# In[37]:
def dRXAP(i, j):
return np.dot(differenceInR(i, j), sumOfP(i, j))
# Function to get division
# In[38]:
def divisionRandP(i, j):
return np.divide(dRXAP(i, j), np.square(sumOfP(i, j)))
# In[43]:
for (i, j) in ids_pairs:
def f(t):
return sqrt(sum(map(lambda i : i * i, np.subtract(differenceInRSquare(i, j), divisionRandP(i, j)))))
fmin(f, 0)
# In[44]:
I was looking at scipy but I am not sure how to use it here, any help is appreciated.
You can use scipy.optimize.fmin like this.
from scipy.optimize import fmin
def f(t):
return 3 * t ** 2 + 3 * t + 3
fmin(f, 0) # -0.5
Note that you have to provide a starting value x0.
For your more complicated function it works the same:
def f(t):
return 6.34436761121718 * np.sqrt(
(0.097474416000379 * t + 0.0188371834173637 * (0.494829394598486 - t) ** 2 - 1) ** 2 + 0.304869715505419 * (
0.097474416000379 * t + 0.062337860997632 * (
0.441516112455913 - t) ** 2 - 1) ** 2 + 0.0416140775153019 * (
0.097474416000379 * t + 0.114241389774407 * (t + 0.958019398183372) ** 2 - 1) ** 2)
fmin(f, 0) # 3.726625
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.