1
$\begingroup$

I want to perform an integration of f[w,t,kx,ky] over t for several different functions f. The f depend on a time t, is w-periodic in it and also depends on two factors kx and ky. The function is very complicated. So I decided to integrate it for fixed kx and ky and then interpolate between those.

I have several w for which I want to do this individually. In the end, I want a, kx- and ky-dependent function for each of these (depending on the inserted function f).

The concept of my code is the following:

MyInterpolatedIntegration[f_, w_, kLimit_, kSteps_, kx_, ky_] :=
  MyInterpolation[MyIntegration[f[#1, #2, #3?, #4?]&, w], kLimit, kSteps][kx, ky]

MyIntegration[function_, w_] := 
  Integrate[Exp[(*something*)] function[w, t], {t, 0, 2 Pi/w}]

MyInterpolation[function_, kLimit_, kSteps_] := 
  MyInterpolation[function, kLimit, kSteps] =
    Interpolation[
      Flatten[
        Table[
          {{κx, κy}, function[κx, κy]},
          {κx, -kLimit, kLimit, 2 kLimit/kSteps},
          {κy, -kLimit, kLimit, 2 kLimit/kSteps}],
        1]]
(* -kLimit to +kLimit with kSteps intermediate steps for both kx and ky *)

I want to pass f[#1, #2, #3, #4] into MyInterpolation, which again should pass f[#1, #2, kx, ky] (with fixed kx and ky) to MyIntegration, which should then perform the integral of f[w, t, kx, ky] over t (for fixed kx, ky, w).

My problem now is that I don't know how to control that #1 becomes w, #2 becomes t and #3 and #4 become kx and ky (therefore the ?-marks in my code). I can only manage to control the first insertion of arguments. How do you pass a function with free parameters after already inserting some?

(The actual problem is a little more involved and contains functions like Eigensystem. For the sake of readability, I've tried to narrow the problem down to the smallest reasonable problem.)

Edit:

(I have also fixed an error in my definition of MyInterpolatedIntegration)

According to request, let me provide an example of what my functions should do. At first let's say f and MyIntegration do the following`:

f[w_, t_, kx_, ky_]:= (1+Sin[w*t])*kx*ky
MyIntegration[function_, w_] :=
    Integrate[Exp[I*w*t] function[w, t], {t, 0, 2 Pi/w}]

Then I can perform an integration the following way:

In[1]:= MyIntegration[f[#1, #2, 1, 1] &, 1]
Out[1]= I Pi

for w=1 and kx = ky = 1.

Now I want a similar call for the MyInterpolationFunction like

In[2]:= MyInterpolation[f[2Pi/3, 0, #1, #2]&, 4, 10]
Out[2]= InterpolatingFunction[(*something*)

Here I used the fixed w = 2Pi/3, t = 0 and have an interpolation for kx and ky both running from -4 to 4 with 10 steps respectively, i.e. the interpolation function will have 100 points to interpolate.

What I'm looking for now, is a function MyInterpolatedIntegration which does both the integration depending on w and the interpolation for kx and ky. I want to call this function in a way similar to

In[3]:= MyInterpolatedIntegration[f[#1, #2, #3, #4]&, 4, 10, 2Pi/3, 1, 2]
Out[3]= 2 (* I think; maybe I made a mistake here *)]

i.e. I want a function that gives me interpolated value for the integral of f evaluated at the corresponding entries (here w = 2Pi/3, kx=1, ky=2 where the interpolation goes from kx,ky = -4 to kx,ky = 4 with 10 respective intermediate steps).

My problem is that I can't simply call f[#1, #2, #3, #4]& as an argument. Instead, I need to tell the function in a different manner when every respective parameter will be inserted.

$\endgroup$
  • $\begingroup$ I think it would be much easier to understand what you are asking if you added example code showing your three defined function in action (i.e., with some actual values) and giving the expected results. $\endgroup$ – m_goldberg Feb 13 '19 at 17:15
  • $\begingroup$ I have tried to provide a good example, and I have also fixed an error in my previous definitions. I hope that's enough to understand well what I mean. If there are further questions, I will answer them tomorrow, but now I have to leave. Thank you so far for your comment. $\endgroup$ – Fred Feb 13 '19 at 17:44
  • $\begingroup$ MyIntegration retuns a scalar for a symbol assigned a value, w = 4 or a function of one variable for an unassigned symbol, w. You are passing the former so what are to expecting to interpolate from a single scalar variable? $\endgroup$ – Edmund Feb 14 '19 at 12:27
  • $\begingroup$ At most MyIntegration will be a scalar or a function of one variable. However, MyInterpolation is expecting a function of two variables. So there are some issues in your concepts that need to be clarified. $\endgroup$ – Edmund Feb 14 '19 at 12:33
  • $\begingroup$ I want to integrate f which depends on w, t, kx and ky over t, such that the resulting scalar depends on w, kx and ky. I will do this for fixed values of w. Thus, the scalar corresponding for a specific w will depend on kx and ky, respectively. This dependence on kx and ky I want to interpolate. (Please note that the integration is only a placeholder. What I actually want to do with f is much more complicated.) The problem is that I want to do the integration with two parameters of f while I want to do the interpolation with the other two. $\endgroup$ – Fred Feb 14 '19 at 12:35
2
$\begingroup$

You are having issues because you are assigning values to your symbols too early in the process; namely the integration.

MyIntegration retuns a scalar for a symbol assigned a value, w = 4 or a function of one variable for an unassigned symbol, w. You are passing the former so what are to expecting to interpolate from a single scalar variable? At most MyIntegration will be a scalar or a function of one variable. However, MyInterpolation is expecting a function of two variables.

How to fix this? Integrate with respect to both remaining variables so that you have a function of 2 variables as a result. You can use Evaluate to assist as it will force the evaluation inside of Function and allow you to use the named variables as inputs to the resulting pure function.

The definitions become:

ClearAll[MyIntegration]
MyIntegration[function_, w_Symbol, t_Symbol] :=
 Integrate[Exp[I*w*t] function[w, t], w, t]

MyInterpolation is as in OP.

ClearAll[MyInterpolatedIntegration];
MyInterpolatedIntegration[f_, w_Symbol, t_Symbol, kLimit_, kSteps_, kx_, ky_] :=
 MyInterpolation[
  Function[{w, t},
   Evaluate[MyIntegration[f[#1, #2, kx, ky] &, w, t]]
   ],
  kLimit, kSteps]

w and t will syntax highlight red as a warning as in most cases you do not want to reuse the function variables within an inner function in this way but it is okay in this particular corner case.

and f as in OP

f[w_, t_, kx_, ky_] := (1 + Sin[w*t])*kx*ky

Then

ClearAll[h, g]
MyInterpolatedIntegration[f, h, g, 10, 2 Pi/3, 1, 2]

Mathematica graphics

ContourPlot[#@if[x, y], 
   {x, Sequence @@ First@if["Domain"]}, 
   {y, Sequence @@ Last@if["Domain"]}, 
   PlotLabel -> #] & /@ {Re, Im}

Mathematica graphics

Hope this helps.

| improve this answer | |
$\endgroup$
  • $\begingroup$ Thank you a lot! Actually, your suggestion doesn't solve my problem the way I intended (I wanted to interpolate in kx and ky). However, it is the correct way of doing it. If I define MyInterpolatedIntegration[w_, kx_, ky_]:= (MyInterpolation[Function[{KX, KY}, MyIntegration[f[#1, #2, KX, KY]&, 2 Pi/3]][#1,#2]&, 4, 10])[kx, ky], it works (with the other functions defined like in my original post). What I needed was a way to get these additional #1 and #2, and Function did the trick. $\endgroup$ – Fred Feb 14 '19 at 13:03
3
$\begingroup$

Perhaps you can use ParametricNDSolveValue instead. For your example:

pf = ParametricNDSolveValue[
    {g'[t] == Exp[I w t] (1+Sin[w t]) kx ky, g[0]==0},
    g[2Pi/w],
    {t, 0, 2Pi/w},
    {w, kx, ky}
];

Then for w=1, kx=1, ky=1:

pf[1, 1, 1]

-2.65328*10^-8 + 3.14159 I

And, for w=2Pi/3, kx=1, ky=2:

pf[2Pi/3, 1, 2]

-2.53459*10^-8 + 3. I

| improve this answer | |
$\endgroup$
  • $\begingroup$ Thank you for the answer. However, this seems to only work for an integration. I used MyIntegration as a placeholder. The actual function I have is much more involved. (It uses the integration only as part of a Fourier decomposition to create a large matrix out of the Fourer coefficients to then get the eigensystem of this matrix and generate a function out of them.) So this, unfortunately, won't solve my actual problem. But your suggestion indeed solves the particular problem I presented. $\endgroup$ – Fred Feb 14 '19 at 10:25
0
$\begingroup$

I am now using a workaround:

MyInterpolatedIntegration[w_, kx_, ky_] := 
    (MyInterpolation[MyIntegration[f[#1, #2, "#1", "#2"] &, 2 Pi/3], 4, 10])[kx, ky]

with a change in my interpolation function:

MyInterpolation[function_, kLimit_, kSteps_] := MyInterpolation[function, kLimit, kSteps] =
    Interpolation[
         Flatten[Table[{{κx, κy}, function /. {"#1" -> κx, "#2" -> κy}},
             {κx, -kLimit, kLimit, 2 kLimit/kSteps}, {κy, -kLimit, kLimit, 2 kLimit/kSteps}],
         1]
    ]

This way, the parameters for MyInterpolation will always have to be called "#1" and "#2" with quotes. I don't like this "solution", because I will need to keep track of how I call my parameters inside all my functions, but since I won't nest things like these too deeply, I am okay with this. Out of curiousity, however, I won't (yet) mark this as a solution, because I would love to know a more elegant way to do it.

| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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