Skip to main content
rewrote the question for clarity and brevity
Source Link
FalafelPita
  • 855
  • 5
  • 16

Why does NIntegrate say integrand not numerical?or NExpectation a vector function

EDIT/UPDATE:Question How do I cut down the numberuse NIntegrate/NExpectation to integrate over a vector function for which each element is a function of parameters anda common solution to an underlying equation?

Background I know that NIntegrate can integrate vectors, but according to a comment to this question, the sizevector structure of the output must be particularly obvious to NIntegrate. The comment constrasts NIntegrate[{Sin[x],Cos[x]},{x,0,1}], which will work, with f[x_?NumericQ]:={Sin[x],Cos[x]}; NIntegrate[f[x],{x,0,1}], which does not work. In the example that works, the vector can be written in an obvious way because each element can be calculated completely separately from the others. I don't know how to make the code/example more "minimal"vector structure apparent to NIntegrate when each element of my vector function needs the root of an equation that I want avoid solving separately for each element of the vector.

Details To be more specific, I need to solve for the smallest root greater than zero of a function of the incomplete Beta function, its first derivative, and a few parametersparameter. $$x^*(k) = \min\{x: x> 0 \text{ and } B(1,2,2) - B(x,2,2) - kx(1-x) = 0\}$$ for which $B()$ is the incomplete beta function, and $B^{\prime}() = x(1-x)$ is its first derivative.

Then, using this solution, I calculate a vector of objects of interest (for simplicity, I'm focusing on just two elements in my example) $\{\frac{B(x^*(k),2,2)}{(B(1,2,2)}, \frac{B(x^*(k),3,2)}{B(x^*(k),2,2)}\}$

Finally, I want to give the parameter a distribution and integrate the vector of interest over that distribution.

Clear[f, xClear[x, impliedCapF0equation, startVals, modelOutcomes]; f[x_] = x*(1 - x); impliedCapF0[x_equation[x_?NumericQ, const_]param_] := Beta[2,2] - Beta[x, 2, 2] +- f[x]*const;x*(1 - x)*param;  startVals = Range[1/10, 9/10, 1/10]; (*initial values for FindRoot*) modelOutcomes[cost_modelOutcomes[param_?NumericQ] := Module[ {capF0 = Beta[2, 2], xSoln,  result1, result2}, (*find the smallest root greater than 0 *) xSoln = Min[ Part[ FindRoot[   capF0 - impliedCapF0[xValFindRoot[equation[xVal, cost/80000]param], {xVal, #,  0, 1}] & /@ startVals, All, 1, 2] ]; (*calculate results*) result1 = Beta[xSoln, 2, 2] /capF0; Beta[2, 2]; result2 = Beta[xSoln, 3, 2] / Beta[xSoln, 2, 2];   {result1, result2} ]; 

I want to give the parameters a joint density and integrate the vector of interest over that density.

  mu = 8;1/10; sigma = 1/800;1000; NExpectation[modelOutcomes[z1] , z1 \[Distributed] LogNormalDistribution[mu, sigma]] (* Integrand modelOutcomes[E^8modelOutcomes[E^(1/10) z1] Piecewise[{{(400500 E^(-320000500000 Log[z1]^2) Sqrt[2/\[Pi]])/z1,z1>0}},0] is not numerical at {z1}={250.34090521920675`}*) 

Why am I being told the Integrand is not numerical? I'm using the ?NumericQ pattern test on the arguments. And ifSo as I plug in the value shown in the stack trace forhave written the error, namely 250.34090521920675*Exp[8] for z1code, the function has no problems producing a numerical result

modelOutcomes[250.34090521920675*Exp[8]] (*{0.000979518, 0.0121014}*) 

And NIntegrate doesn't seemNIntegrate is unable to havesee and expect a problem with the vector per seoutput from the Integrand, because it integrates a constant vector without problem

NExpectation[modelOutcomes[10000], z1 \[Distributed] LogNormalDistribution[mu, sigma]] (*{0.434068, 0.223295}*) 

What do I need to change sotelling me that NExpectation handles this without error?the output is "not numerical."

Update If If I alter modelOutcomes so that it returns a scalarjust result1, then NExpectation works. If I alter it to return a list of length 1, containing the same scalar{result1}, it gives me the same "not numerical" error. So I wonder if this is about the function returning a vector/list.

Update According to a comment to this question, NIntegrate needsproblem seems to know that the function produces a vector. The comment constrastsbe about getting NIntegrate[{Sin[x],Cos[x]},{x,0,1}], which will work, with f[x_?NumericQ]:={Sin[x],Cos[x]}; NIntegrate[f[x],{x,0,1}]NIntegrate, which does not work. The challenge in my application is that I need to find the root of an underlying function and use that result to calculate each element of the outcomes vector. If I treat each element of theexpect a vector completely separately I will have to find the root separately, which I need to avoid to keep computation time reasonableintegrand.

Why does NIntegrate say integrand not numerical?

EDIT/UPDATE: I cut down the number of parameters and the size of the output vector to make the code/example more "minimal".

I need to solve for the smallest root greater than zero of a function of the incomplete Beta function, its first derivative, and a few parameters. Then, using this solution, I calculate a vector of objects of interest.

Clear[f, x, impliedCapF0, startVals, modelOutcomes]; f[x_] = x*(1 - x); impliedCapF0[x_, const_] := Beta[x, 2, 2] + f[x]*const; startVals = Range[1/10, 9/10, 1/10]; modelOutcomes[cost_?NumericQ] := Module[ {capF0 = Beta[2, 2], xSoln,  result1, result2}, (*find the smallest root greater than 0 *) xSoln = Min[ Part[ FindRoot[   capF0 - impliedCapF0[xVal, cost/80000], {xVal, #,  0, 1}] & /@ startVals, All, 1, 2] ]; (*calculate results*) result1 = Beta[xSoln, 2, 2]/capF0; result2 = Beta[xSoln, 3, 2] / Beta[xSoln, 2, 2]; {result1, result2} ]; 

I want to give the parameters a joint density and integrate the vector of interest over that density.

mu = 8; sigma = 1/800; NExpectation[modelOutcomes[z1] , z1 \[Distributed] LogNormalDistribution[mu, sigma]] (* Integrand modelOutcomes[E^8 z1] Piecewise[{{(400 E^(-320000 Log[z1]^2) Sqrt[2/\[Pi]])/z1,z1>0}},0] is not numerical at {z1}={250.34090521920675`}*) 

Why am I being told the Integrand is not numerical? I'm using the ?NumericQ pattern test on the arguments. And if I plug in the value shown in the stack trace for the error, namely 250.34090521920675*Exp[8] for z1, the function has no problems producing a numerical result

modelOutcomes[250.34090521920675*Exp[8]] (*{0.000979518, 0.0121014}*) 

And NIntegrate doesn't seem to have a problem with the vector per se, because it integrates a constant vector without problem

NExpectation[modelOutcomes[10000], z1 \[Distributed] LogNormalDistribution[mu, sigma]] (*{0.434068, 0.223295}*) 

What do I need to change so that NExpectation handles this without error?

Update If I alter modelOutcomes so that it returns a scalar, then NExpectation works. If I alter it to return a list of length 1, containing the same scalar, it gives me the "not numerical" error. So I wonder if this is about the function returning a vector/list.

Update According to a comment to this question, NIntegrate needs to know that the function produces a vector. The comment constrasts NIntegrate[{Sin[x],Cos[x]},{x,0,1}], which will work, with f[x_?NumericQ]:={Sin[x],Cos[x]}; NIntegrate[f[x],{x,0,1}], which does not work. The challenge in my application is that I need to find the root of an underlying function and use that result to calculate each element of the outcomes vector. If I treat each element of the vector completely separately I will have to find the root separately, which I need to avoid to keep computation time reasonable.

NIntegrate or NExpectation a vector function

Question How do I use NIntegrate/NExpectation to integrate over a vector function for which each element is a function of a common solution to an underlying equation?

Background I know that NIntegrate can integrate vectors, but according to a comment to this question, the vector structure of the output must be particularly obvious to NIntegrate. The comment constrasts NIntegrate[{Sin[x],Cos[x]},{x,0,1}], which will work, with f[x_?NumericQ]:={Sin[x],Cos[x]}; NIntegrate[f[x],{x,0,1}], which does not work. In the example that works, the vector can be written in an obvious way because each element can be calculated completely separately from the others. I don't know how to make the vector structure apparent to NIntegrate when each element of my vector function needs the root of an equation that I want avoid solving separately for each element of the vector.

Details To be more specific, I need to solve for the smallest root greater than zero of a function of the incomplete Beta function, its first derivative, and a parameter. $$x^*(k) = \min\{x: x> 0 \text{ and } B(1,2,2) - B(x,2,2) - kx(1-x) = 0\}$$ for which $B()$ is the incomplete beta function, and $B^{\prime}() = x(1-x)$ is its first derivative.

Then, using this solution, I calculate a vector of objects of interest (for simplicity, I'm focusing on just two elements in my example) $\{\frac{B(x^*(k),2,2)}{(B(1,2,2)}, \frac{B(x^*(k),3,2)}{B(x^*(k),2,2)}\}$

Finally, I want to give the parameter a distribution and integrate the vector of interest over that distribution.

Clear[x,equation, startVals, modelOutcomes]; equation[x_?NumericQ, param_] := Beta[2,2] - Beta[x, 2, 2] - x*(1 - x)*param;  startVals = Range[1/10, 9/10, 1/10]; (*initial values for FindRoot*) modelOutcomes[param_?NumericQ] := Module[{xSoln, result1, result2}, (*find the smallest root greater than 0 *) xSoln = Min[ Part[ FindRoot[equation[xVal, param], {xVal, #, 0, 1}] & /@ startVals, All, 1, 2] ]; (*calculate results*) result1 = Beta[xSoln, 2, 2] / Beta[2, 2]; result2 = Beta[xSoln, 3, 2] / Beta[xSoln, 2, 2];   {result1, result2} ];   mu = 1/10; sigma = 1/1000; NExpectation[modelOutcomes[z1] , z1 \[Distributed] LogNormalDistribution[mu, sigma]] (* Integrand modelOutcomes[E^(1/10) z1] Piecewise[{{(500 E^(-500000 Log[z1]^2) Sqrt[2/\[Pi]])/z1,z1>0}},0] is not numerical at {z1}={250.34090521920675`}*) 

So as I have written the code, NIntegrate is unable to see and expect a vector output from the Integrand, telling me that the output is "not numerical."

If I alter modelOutcomes so that it just result1, then NExpectation works. If I alter it to return a {result1}, it gives me the same "not numerical" error. So the problem seems to be about getting NIntegrate to expect a vector integrand.

trim down the minimal example more, so modelOutcomes takes a single argument. Added more info learned from another question
Source Link
FalafelPita
  • 855
  • 5
  • 16
Clear[f, x, impliedCapF0, startVals, modelOutcomes]; f[x_] = x*(1 - x); impliedCapF0[x_, const_] := Beta[x, 2, 2] + f[x]*const; startVals = Range[1/10, 9/10, 1/10]; modelOutcomes[cost1_?NumericQ, cost2_modelOutcomes[cost_?NumericQ] := Module[ {capF0 = Beta[2, 2], xSoln, result1, result2}, (*find the smallest root greater than 0 *) xSoln = Min[ Part[ FindRoot[ capF0 - impliedCapF0[xVal, (cost1 + cost2)cost/80000], {xVal, #, 0, 1}] & /@ startVals, All, 1, 2] ]; (*calculate results*) result1 = Beta[xSoln, 2, 2]/capF0; result2 = Beta[xSoln, 3, 2] / Beta[xSoln, 2, 2]; {result1, result2} ]; 
mu = {8,8; 8}; sigma = {{1/800, 1/1000}, {1/1000, 1/800}};800; NExpectation[modelOutcomes[z1, z2]NExpectation[modelOutcomes[z1] , {z1, z2} \[Distributed] LogMultinormalDistribution[muLogNormalDistribution[mu, sigma]] (* Integrand modelOutcomes[E^8 z1,E^8 z2]z1] Piecewise[{{(2000400 E^(1/2 (-Log[z1] ((20000 Log[z1])/9-(16000 Log[z2])/9)-Log[z2] (-((16000320000 Log[z1])/9Log[z1]^2)+(20000 Log[z2])Sqrt[2/9)))\[Pi]])/(3 \[Pi] z1 z2),z1>0&&z2>0z1>0}},0]] 0] is not numerical at {z1,z2}={3.`,3250.`34090521920675`}*) 

Why am I being told the Integrand is not numerical? I'm using the ?NumericQ pattern test on the arguments. And if I plug in the valuesvalue shown in the stack trace for the error, namely 3*Exp[8]250.34090521920675*Exp[8] for z1 and z2, the function has no problems producing a numerical result

modelOutcomes[3*Exp[8], 3*Exp[8]]modelOutcomes[250.34090521920675*Exp[8]] (*{0.686238000979518, 0.3804140121014}*) 
NExpectation[ modelOutcomes[10000, 5000] NExpectation[modelOutcomes[10000], {  z1, z2} \[Distributed]  LogMultinormalDistribution[muLogNormalDistribution[mu, sigma]] (*{0.753337434068, 0.404454223295}*) 

Update If I alter modelOutcomes so that it returns a scalar, then NExpectation works. If I alter it to return a list of length 1, containing the same scalar, it gives me the "not numerical" error. So I wonder if this is about the function returning a vector/list.

Update According to a comment to this question, NIntegrate needs to know that the function produces a vector. The comment constrasts NIntegrate[{Sin[x],Cos[x]},{x,0,1}], which will work, with f[x_?NumericQ]:={Sin[x],Cos[x]}; NIntegrate[f[x],{x,0,1}], which does not work. The challenge in my application is that I need to find the root of an underlying function and use that result to calculate each element of the outcomes vector. If I treat each element of the vector completely separately I will have to find the root separately, which I need to avoid to keep computation time reasonable.

Clear[f, x, impliedCapF0, startVals, modelOutcomes]; f[x_] = x*(1 - x); impliedCapF0[x_, const_] := Beta[x, 2, 2] + f[x]*const; startVals = Range[1/10, 9/10, 1/10]; modelOutcomes[cost1_?NumericQ, cost2_?NumericQ] := Module[ {capF0 = Beta[2, 2], xSoln, result1, result2}, (*find the smallest root greater than 0 *) xSoln = Min[ Part[ FindRoot[ capF0 - impliedCapF0[xVal, (cost1 + cost2)/80000], {xVal, #, 0, 1}] & /@ startVals, All, 1, 2] ]; (*calculate results*) result1 = Beta[xSoln, 2, 2]/capF0; result2 = Beta[xSoln, 3, 2] / Beta[xSoln, 2, 2]; {result1, result2} ]; 
mu = {8, 8}; sigma = {{1/800, 1/1000}, {1/1000, 1/800}}; NExpectation[modelOutcomes[z1, z2] , {z1, z2} \[Distributed] LogMultinormalDistribution[mu, sigma]] (* Integrand modelOutcomes[E^8 z1,E^8 z2] Piecewise[{{(2000 E^(1/2 (-Log[z1] ((20000 Log[z1])/9-(16000 Log[z2])/9)-Log[z2] (-((16000 Log[z1])/9)+(20000 Log[z2])/9))))/(3 \[Pi] z1 z2),z1>0&&z2>0}},0]]  is not numerical at {z1,z2}={3.`,3.`}*) 

Why am I being told the Integrand is not numerical? I'm using the ?NumericQ pattern test on the arguments. And if I plug in the values shown in the stack trace for the error, namely 3*Exp[8] for z1 and z2, the function has no problems producing a numerical result

modelOutcomes[3*Exp[8], 3*Exp[8]] (*{0.686238, 0.380414}*) 
NExpectation[ modelOutcomes[10000, 5000] , {z1, z2} \[Distributed]  LogMultinormalDistribution[mu, sigma]] (*{0.753337, 0.404454}*) 

Update If I alter modelOutcomes so that it returns a scalar, then NExpectation works. If I alter it to return a list of length 1, containing the same scalar, it gives me the "not numerical" error. So I wonder if this is about the function returning a vector/list.

Clear[f, x, impliedCapF0, startVals, modelOutcomes]; f[x_] = x*(1 - x); impliedCapF0[x_, const_] := Beta[x, 2, 2] + f[x]*const; startVals = Range[1/10, 9/10, 1/10]; modelOutcomes[cost_?NumericQ] := Module[ {capF0 = Beta[2, 2], xSoln, result1, result2}, (*find the smallest root greater than 0 *) xSoln = Min[ Part[ FindRoot[ capF0 - impliedCapF0[xVal, cost/80000], {xVal, #, 0, 1}] & /@ startVals, All, 1, 2] ]; (*calculate results*) result1 = Beta[xSoln, 2, 2]/capF0; result2 = Beta[xSoln, 3, 2] / Beta[xSoln, 2, 2]; {result1, result2} ]; 
mu = 8; sigma = 1/800; NExpectation[modelOutcomes[z1] , z1 \[Distributed] LogNormalDistribution[mu, sigma]] (* Integrand modelOutcomes[E^8 z1] Piecewise[{{(400 E^(-320000 Log[z1]^2) Sqrt[2/\[Pi]])/z1,z1>0}},0] is not numerical at {z1}={250.34090521920675`}*) 

Why am I being told the Integrand is not numerical? I'm using the ?NumericQ pattern test on the arguments. And if I plug in the value shown in the stack trace for the error, namely 250.34090521920675*Exp[8] for z1, the function has no problems producing a numerical result

modelOutcomes[250.34090521920675*Exp[8]] (*{0.000979518, 0.0121014}*) 
NExpectation[modelOutcomes[10000],   z1 \[Distributed] LogNormalDistribution[mu, sigma]] (*{0.434068, 0.223295}*) 

Update If I alter modelOutcomes so that it returns a scalar, then NExpectation works. If I alter it to return a list of length 1, containing the same scalar, it gives me the "not numerical" error. So I wonder if this is about the function returning a vector/list.

Update According to a comment to this question, NIntegrate needs to know that the function produces a vector. The comment constrasts NIntegrate[{Sin[x],Cos[x]},{x,0,1}], which will work, with f[x_?NumericQ]:={Sin[x],Cos[x]}; NIntegrate[f[x],{x,0,1}], which does not work. The challenge in my application is that I need to find the root of an underlying function and use that result to calculate each element of the outcomes vector. If I treat each element of the vector completely separately I will have to find the root separately, which I need to avoid to keep computation time reasonable.

update about results with scalar vs. list
Source Link
FalafelPita
  • 855
  • 5
  • 16

Update If I alter modelOutcomes so that it returns a scalar, then NExpectation works. If I alter it to return a list of length 1, containing the same scalar, it gives me the "not numerical" error. So I wonder if this is about the function returning a vector/list.

Update If I alter modelOutcomes so that it returns a scalar, then NExpectation works. If I alter it to return a list of length 1, containing the same scalar, it gives me the "not numerical" error. So I wonder if this is about the function returning a vector/list.

Cut out parameters and reduced size of output vector to make the code simpler to understand.
Source Link
FalafelPita
  • 855
  • 5
  • 16
Loading
Source Link
FalafelPita
  • 855
  • 5
  • 16
Loading