简体   繁体   中英

Is there a way to calculate maxima and minima of an express in python?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM