0

I have defined a series of functions below with the end function fA being inserted for a numerical integration. The integration is with respect with one variable so the other arguments are passed as numeric so that the integration method (quad) may proceed

import numpy 
import math as m
import scipy
import sympy

#define constants                                                                                                                                                                    
gammaee = 5.55e-6
MJpsi = 3.096916
alphaem = 1/137
lambdasq = 0.09
Ca = 3
qOsq = 2


def qbarsq(qsq):
    return (qsq+MJpsi**2)/4


def xx(qbarsq, w):
    return 4*qbarsq/(4*qbarsq-MJpsi**2+w**2)

from sympy import *

x,NN,a,b,ktsq,qbarsq,w = symbols('x NN a b ktsq qbarsq w')


def xg(a,b,NN,ktsq,x):
    return NN*(x**(-a))*(ktsq**b)*exp(sqrt((16*Ca/9)*log(1/x)*log((log(ktsq/lambdasq))/(log(qOsq/lambdasq)))))


#prints symbolic derivative of xg                                                                                                                                                    
def func(NN,a,b,x,ktsq):
    return (-x*diff(log(xg(a,b,NN,ktsq,x)),x))
#print(func(NN,a,b,x,ktsq))                                                                                                                                                          



#prints symbolic expression for Rg                                                                                                                                                   
def Rg(NN,a,b,ktsq,x):
    return 2**(2*func(NN,a,b,x,ktsq)+3)/sqrt(m.pi)*gamma(func(NN,a,b,x,ktsq)+5/2)/gamma(func(NN,a,b,x,ktsq)+4)
#print(Rg(NN,a,b,ktsq,x))

#prints symbolic expression for Fktsq                                                                                                                                                
def FktsqDeriv(NN,a,b,x,ktsq):
    return diff(Rg(NN,a,b,ktsq,x)*xg(a,b,NN,ktsq,x),ktsq)
#print(FktsqDeriv(NN,a,b,x,ktsq))                                                                                                                                                   


def Fktsq1(qbarsq,ktsq,NN,a,b,w):
    return FktsqDeriv(NN,a,b,x,ktsq).subs(x,4*qbarsq/(4*qbarsq-MJpsi**2+w**2))
print(Fktsq1(qbarsq,ktsq,NN,a,b,w))

# symbolic expression for fA                                                                                                                                                         
def fA(qbarsq,ktsq,NN,a,b,w):
    return Fktsq1(qbarsq,ktsq,NN,a,b,w)*1/(qbarsq)*1/(qbarsq+ktsq)
#print(fA(qbarsq,ktsq,NN,a,b,w))

I now want to integrate this last function over ktsq as follows,

import scipy.integrate.quadrature as sciquad
def integrated_f(NN,a,b,w,qbarsq):
    return sciquad(fA,1,(w**2-MJpsi**2)/4, args=(NN, a, b, w, qbarsq))

a=0.1
NN=0.5
b=-0.2
w=89
qbarsq=5
result = integrated_f(NN,a,b,w,qbarsq)
print(result)

The problem is where I try to get a number out from this integration by specifying numerical values for each of the other parameters. The error is

ValueError: Can't calculate 1st derivative wrt 989.426138911118.

My only interpretation of this is that the method cannot cope with the complexity of the function (even though I think it is relatively simple in structure) because I did not define any more derivatives and certainly not with respect to this value. Is there an easy solution? Actually I wish to use the function integrated_f to use in an optimisation problem for best fit parameters a,b,NN. Would something like

scipy.optimize.minimize(integrated_f, x0, method='Nelder-Mead', options={'max\ iter': 1000}) be ok for multivariable functions where x0 is an array of initial guesses. Thanks!

CAF
  • 329
  • 3
  • 14
  • 2
    The function `diff` is not defined in your code. Is that from numpy or sympy? It would help if you created a [minimal, complete and verifiable example](https://stackoverflow.com/help/mcve) that we could copy and run to reproduce the problem. – Warren Weckesser Jan 26 '18 at 16:08
  • @WarrenWeckesser `diff` is from sympy, imported via `from sympy import *`. Regarding the minimal, complete and verifiable example, as mentioned in my question, the problem is specific to the functions I have defined because I have not had problem with the code with other test fA's. When I say the problem 'is' specific, I really mean 'seems to be' because I see no other way to interpret those derivative errors which probably arise because of some underlying differentiability problem in my function or in the way the method is handling it. Thanks! – CAF Jan 26 '18 at 16:14
  • 1
    OK, but the code you show is not runnable as it is. Can you fix it up to make it runnable? I suspect the problem is passing an incorrect argument to the sympy function. – Warren Weckesser Jan 26 '18 at 16:36
  • @WarrenWeckesser I think the first block is runnable ( If I uncomment `print(fA(qbarsq,ktsq,NN,a,b,w))` I get a function returned to me) but with the second block included with the integration method it is not. If I comment out everything below `a=0.1` in the second block it becomes runnable. Do you find the same? It's just how to get the print(result) statement to work that is my issue. – CAF Jan 26 '18 at 16:45
  • 1
    The code in the functions was not indented correctly (fixed now). `quad` cannot handle any sympy expressions. The function to be integrated with `quad` must accept a floating point value as its *first* argument, and it must return a floating point value. Any remaining arguments specified with `args` must be given in the same order as the remaining arguments of the function to be integrated. The way your code is now, you are trying to integrate `f_A` over the `qbarsq` argument, and `args=((NN, a, b, w, qbarsq)`) assigns the remaining args as `ktsq=NN, NN=a, a=b, b=w, w=qbarsg`. – Warren Weckesser Jan 26 '18 at 17:08
  • @WarrenWeckesser Ah, I didn't realise this. So I should define fA as `fA(ktsq,qbarsq,NN,a,b,w)`, integrated_f as `integrated_f(qbarsq,NN,a,b,w)` and args as `args(qbarsq,NN,a,b,w)` (if I understood your comment correctly) ? With these replacements I still get a derivative error which I guess can be fixed with a floating point first argument? How would I make it floating point? – CAF Jan 27 '18 at 11:55
  • @WarrenWeckesser Probably an error is due to me having defined NN,a,b etc as symbolic variables since they partake in differentiation but now I wish to pass them as numeric variables for use in this integration method. I think that is what you alluded to about a floating point function. But how to make the variables numeric? Everything I found online always substitutes a number, e.g in `.subs` or `lambify` function. – CAF Jan 30 '18 at 10:22
  • See if https://stackoverflow.com/questions/35430479/convert-sympy-expressions-to-function-of-numpy-arrays helps. – Warren Weckesser Jan 30 '18 at 14:39

0 Answers0