2
$\begingroup$

Assume I have the following parametrized curve:

trefoil[t_] := {Sin[t] + 2*Sin[2*t], Cos[t] - 2*Cos[2*t], -Sin[3*t]}; 

...and two functions of the vectors $A,B\in\mathbb{R}^3$ defined via

integral1[A_, B_] := Sum[NIntegrate[ Sqrt[u1]*(Ai*Bj) /. {Ai -> A[[i]], Bj -> B[[j]]}, {u1, 0, 1}], {i, 1, 3}, {j, 1, 3}] integral2[A_, B_] := Sum[((Ai*Bj) /. {Ai -> A[[i]], Bj -> B[[j]]})*NIntegrate[Sqrt[u1], {u1, 0, 1}], {i,1, 3}, {j, 1, 3}] 

These two functions are very clearly identical; integral2 differs from integral1 by pulling the coefficients $A_i$ and $B_j$ out of the numerical integration. Upon trying to evaluate these functions at a random point along the above curve via:

integral1[trefoil[t3] - trefoil[t1], trefoil[t1] - trefoil[t2]] /. {t1 -> 0.1, t2 -> 0.2, t3 -> 0.7} integral2[trefoil[t3] - trefoil[t1], trefoil[t1] - trefoil[t2]] /. {t1 -> 0.1, t2 -> 0.2, t3 -> 0.7} 

...I find that the first crashes with error messages concerning non-numerical values, while the second gives a value of -0.61606 with no issues.

My question: does anyone know why the evaluation of integral1 is failing and what I can do to fix my syntax here? I have a more complicated use case in mind, where I cannot pull the constants out of the integrand, but I think this example depicts the issue.

I think the HoldAll attribute is relevant here, but I cannot sort out a solution.

Really appreciate the help!

$\endgroup$
5
  • 1
    $\begingroup$ Does this answer your question?: mathematica.stackexchange.com/a/280488/1871 You'll find more by searching e.g. mathematica.stackexchange.com/… $\endgroup$ Commented Dec 31, 2024 at 5:30
  • 2
    $\begingroup$ Use integral1[A_?(VectorQ[#, NumericQ] &), B_?(VectorQ[#, NumericQ] &)] := ... $\endgroup$ Commented Dec 31, 2024 at 6:43
  • 1
    $\begingroup$ See also mathematica.stackexchange.com/questions/18393/… $\endgroup$ Commented Dec 31, 2024 at 19:43
  • 1
    $\begingroup$ I don't get a crash. What version are you running that crashes? $\endgroup$ Commented Dec 31, 2024 at 21:44
  • $\begingroup$ @DanielLichtblau thanks for taking a look, 11.1.1.0 on Windows $\endgroup$ Commented Dec 31, 2024 at 22:44

2 Answers 2

4
$\begingroup$

@BobHanlon's comment shows the way to go, and the general problem of holding up numerical routines until parameters have numeric values is discuss in this answer to What are the most common pitfalls awaiting new users?

I personally avoid Sum[] for purely numerical summation, since it does symbolic analysis. I use Total@Table[...] unless the memory usage of Table[] is prohibitive. Then I'd use Sum[..., Method -> "Procedural"], which is the way one is "supposed" to calculate numerical sums. And it's just as good as Total@Table and usually a bit faster on large sums. Here's an example to show that a straight Sum[] with a numerical summand can be a disaster:

summand[x_?NumericQ] := x; Sum[summand[x], {x, 1., 10^6 + 1}, Method -> "Procedural"] Sum[summand[x], {x, 1., 10^6 + 1}] (* 5.00002*10^11 Sum[summand[x], {x, 1., 1000001}] *) 

The 10^6 is a limit beyond which Sum[] won't try summing each term. You can reset this in SystemOptions[], but you can see that Method -> "Procedural" is an easier way around the limitation.

That said, here's a cute way to do the calculation at hand using Total[] and Outer[] instead of Sum[]:

ClearAll[integral1, integral2]; integral1[A_?(VectorQ[#, NumericQ] &), B_?(VectorQ[#, NumericQ] &)] := Total[NIntegrate[Sqrt[u1]*Outer[Times, A, B], {u1, 0, 1}], All]; integral2[A_, B_] := Sum[((Ai*Bj) /. {Ai -> A[[i]], Bj -> B[[j]]})* NIntegrate[Sqrt[u1], {u1, 0, 1}], {i, 1, 3}, {j, 1, 3}]; integral1[trefoil[t3] - trefoil[t1], trefoil[t1] - trefoil[t2]] /. {t1 -> 0.1, t2 -> 0.2, t3 -> 0.7} integral2[trefoil[t3] - trefoil[t1], trefoil[t1] - trefoil[t2]] /. {t1 -> 0.1, t2 -> 0.2, t3 -> 0.7} (* -0.61606 -0.61606 *) 
$\endgroup$
1
  • $\begingroup$ Awesome, this is great, and @BobHanlon's comment worked perfectly for my application. I will also take you recommendation on Totaling vs. Sum, as this is going to go into a heavy computation. Appreciate the time all! $\endgroup$ Commented Dec 31, 2024 at 22:46
0
$\begingroup$

Use the trace

 tr = Trace[integral1[trefoil[t3] - trefoil[t1], trefoil[t1] - trefoil[t2]] /. {t1 -> 0.1, t2 -> 0.2, t3 -> 0.7}]; NIntegrate::inumr : The integrand Sqrt[ u1] (Sin[t1] + 2 Sin[2 t1] - Sin[t2] - 2 Sin[2 t2]) (-Sin[t1] - 2 Sin[2 t1] + Sin[t3] + 2 Sin[2 t3]) has evaluated to non - numerical values for all sampling points in the region with boundaries {{0, 1}}. tr[[1, 5, -10 ;; -1 ]] {{u1=.,Null},{u1=.,Null},{u1=.,Null},{u1=.,Null},{u1=.,Null},{u1=.,Null}, {u1=.,Null},{u1=.,Null},{Message[NIntegrate::inumr,Sqrt[u1] (Sin[t1]+2 Sin[2 t1]- Sin[t2]-2 Sin[2 t2]) (-Sin[t1]-2 Sin[2 t1]+Sin[t3]+2 Sin[2 t3]),{{0,1}}], {NIntegrate::inumr,The integrand `1` has evaluated to non-numerical values for all sampling points in the region with boundaries `2`. 

There seems to occure a violation of the principle not to pass non-numeric symbols to the NIntegrate module from the list of sample points for numerical evaluations.

Generally, Replace procedures inside modules with Hold arguments are difficult to control.

$\endgroup$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.