5
$\begingroup$

Consider the following module:

computation[i_, j_] := Module[{func, fintt, fintt2},
  func[x_, y_, t_] = 
   Exp[-(y^i + j*x^2)*t^3 + -(i*y + j*x^2)*t^4]*Cos[i^3*y*t^5];
  fintt[t_] = 
   Interpolation[
     Table[{t, 
       NIntegrate[func[x, y, t], {x, 0.1, 2}, {y, 0.2, x}]}, {t, 0., 
       0.5, 0.05}], InterpolationOrder -> 1][t];
  fintt2[t_] = 
   If[i > 0 && j > 0 && t > 0, fintt[t]^j*Cos[t*i]^j, fintt[t]];
  {i, j, fintt[t], fintt2[t]}]

Let us test it:

funcTest[t_]=computation[1,2]
funcTest[2]

Enter image description here

My problem is already described in this question. In short, if trying to export the content funcTest[t] and then importing it after quitting the kernel, the system forgets what is fintt$3487[t], and does not return the function when trying to use it. Let us also assume that:

1) It is not possible to make fintt global.

2) The If[] condition cannot be put out of the Module environment.

The difference, in this case, is that the If condition is applied to a kind of implicit function. How can I fix this issue?

$\endgroup$

3 Answers 3

6
$\begingroup$

Your issue results from the fact that If holds its second and third arguments:

Attributes[If] (* {HoldRest, Protected} *)

This is a desired property - e.g., it lets you write code like this and not be worried about a division by zero:

reciprocal[a_] := If[a != 0, 1/a, $Failed]
In[159]:= reciprocal /@ {0, 1, 2}
Out[159]= {$Failed, 1, 1/2}

Compare to a function that doesn't hold its arguments:

myIf[a_, b_, c_] := If[a, b, c]
reciprocal1[a_] := myIf[a != 0, 1/a, $Failed]
reciprocal1[0]

enter image description here

The error message is printed because all of the arguments of myIf are evaluated before being passed to If.

So to solve your problem, you need to force the evaluation of Ifs arguments in computation:

computation[i_, j_] := 
 Module[{func, fintt, fintt2}, 
  func[x_, y_, t_] = 
   Exp[-(y^i + j*x^2)*t^3 + -(i*y + j*x^2)*t^4]*Cos[i^3*y*t^5];
  fintt[t_] = 
   Interpolation[
     Table[{t, 
       NIntegrate[func[x, y, t], {x, 0.1, 2}, {y, 0.2, x}]}, {t, 0., 
       0.5, 0.05}], InterpolationOrder -> 1][t];
  fintt2[t_] = 
   If[i > 0 && j > 0 && t > 0, Evaluate[fintt[t]^j*Cos[t*i]^j], 
    Evaluate@fintt[t]];
  {i, j, fintt[t], fintt2[t]}]

computation[1, 2][2]

enter image description here

$\endgroup$
4
$\begingroup$

I may not be grokking what you're going for, but maybe this:

computation[i_, j_] :=
  Module[
    {func, fintt, fintt2},
    func[x_, y_, t_] = Exp[-(y^i + j*x^2)*t^3 + -(i*y + j*x^2)*t^4]*Cos[i^3*y*t^5];
    fintt =
      Interpolation[
        Table[
          {t, NIntegrate[func[x, y, t], {x, 0.1, 2}, {y, 0.2, x}]},
          {t, 0., 0.5, 0.05}], 
        InterpolationOrder -> 1] &;
    fintt2 = If[i > 0 && j > 0 && # > 0, fintt[#]^j*Cos[#*i]^j, fintt[#]] &;
    {i, j, fintt[#], fintt2[#]} &]

Then

funcTest = computation[1, 2];
funcTest[2]

Since you've used t as both a table iterator and an argument name, I'm not sure if I interpreted things correctly. It also seems like there would be an easier way to do this whole thing, but it seems like you have several strong constraints, so I'm not sure what can be changed.

$\endgroup$
4
$\begingroup$

You should be able to use Piecewise instead of If:

computation[i_, j_] := 
 Module[{func, fintt, fintt2}, 
  func[x_, y_, t_] = 
   Exp[-(y^i + j*x^2)*t^3 + -(i*y + j*x^2)*t^4]*Cos[i^3*y*t^5];
  fintt[t_] = 
   Interpolation[
     Table[{t, 
       NIntegrate[func[x, y, t], {x, 0.1, 2}, {y, 0.2, x}]}, {t, 0., 
       0.5, 0.05}], InterpolationOrder -> 1][t];
  fintt2[t_] = 
   Piecewise[{{fintt[t]^j*Cos[t*i]^j, i > 0 && j > 0 && t > 0}}, 
    fintt[t]];
  {i, j, fintt[t], fintt2[t]}]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.