4

I am using this from the function repository for which I need to convert one of my functions into a unique form. A simple example is like this:

Suppose I have,

H[px_, py_, x_, y_] := 1/2 (px^2 + py^2) + (x^2 + y^2) + 1/2 x^2 y^2

and I need to convert this into a pure function with a particular form:

H := Function[{S}, 1/2 (S[[2]]^2 + S[[4]]^2) + S[[1]]^2 + S[[3]]^2 + 1/2 S[[1]]^2 S[[3]]^2]

The simple way I do this is by using,

H[px, py, x, y] /. x -> S[[1]] /. px -> S[[2]] /. y -> S[[3]] /. py -> S[[4]]

But this approach gives me warning messages. Is there a more elegant way by which I can automate the entire process?

codebpr
  • 2,233
  • 1
  • 7
  • 26
  • hPure = H[#[[2]], #[[4]], #[[1]], #[[3]]] & ? – Domen Mar 04 '24 at 08:18
  • Or simply turn off the warning messages: hPure = H[px, py, x, y] /. {x -> S[[1]], px -> S[[2]], y -> S[[3]], py -> S[[4]]} // Quiet. It's not entirely clear what the actual final form should be. Which function from the WFR are you using? – Domen Mar 04 '24 at 08:27
  • @Domen Actually H stands for hamiltonian. I am dealing with a system with magnetic field, so every time I change the value of the field, my hamiltonian changes, now if I wish to use the hamiltonian that I calculated to generate a Poincare section using this resource function, I have to alter it's form. It's a repetitive process so manually doing it every time is not so efficient, that's why I was searching for some automation. – codebpr Mar 04 '24 at 09:06
  • But there is no magnetic field in the Hamiltonian you provided. How are you changing it? You can just do hMagnetic[b_] := Function[{S}, 1/2 (S[[2]]^2 + S[[4]]^2 + S[[1]]^2 + S[[3]]^2) + 2*S[[1]]^2 S[[3]] + b S[[3]]], and then call ResourceFunction["ClickPoincarePlot2D"][..., hMagnetic[0.1], ...]. Please provide more concrete example of what you are using, otherwise, it seems like an XY problem. – Domen Mar 04 '24 at 09:20
  • 3
    The warning message that I am getting with a clean kernel is "Part specification S[[1]] is longer than depth of object" which makes sense since S is undefined. – bmf Mar 04 '24 at 09:22
  • @Domen, it's not. I said, "Every time I change the value of the field, my Hamiltonian changes". I never said, "field is incorporated in the Hamiltonian, which retains its structure." Magnetic field altering the system implies, that for each magnetic field, I have a different Hamiltonian, for which one of the simplest examples I have provided. – codebpr Mar 04 '24 at 12:27

3 Answers3

5

The minimal method to get your code to work, is to just define your H as:

H[{px_, py_, x_, y_}] := 1/2 (px^2 + py^2) + (x^2 + y^2) + 1/2 x^2 y^2

and then call:

ResourceFunction["ClickPoincarePlot2D"][{eq1, ...}, H[#]&, ...]
Sjoerd Smit
  • 23,370
  • 46
  • 75
4

Just use RuleDelayed (:>) instead of Rule (->):

pureH = Function[S, H[px, py, x, y] // Evaluate] /. x :> S[[1]] /. px :> S[[2]] /. 
  y :> S[[3]] /. py :> S[[4]]
xzczd
  • 65,995
  • 9
  • 163
  • 468
3

We can make a scalar version of the TensorPureFunction function as follows:

ScalarPureFunction[f_, 
    argvars_?
     VectorQ] /; (SameQ[Length[Variables[Level[f, {-1}]]], 
      Length[Flatten[argvars]]] && Length[argvars] > 1) := Module[
    {positions, heldPart, replacements},
    positions = MapIndexed[List, argvars, {-1}];
    heldPart = MapThread[
            Function[
  HoldForm[Part][\[FormalP], 
   Apply[Sequence, Part[SlotSequence @ 1, 2, All]]]
        ],
        {positions}
    ];
replacements = Thread[argvars -> heldPart];
ReleaseHold[
Fold[Function[#, #2] &, {\[FormalP]}, {f /. replacements}]]

];

ScalarPureFunction[f_][argvars_?VectorQ] := ScalarPureFunction[f, argvars];

Testing ScalarPureFunction:

ScalarPureFunction[1/2  (px^2 + py^2 + x^2 + y^2) + 1/2  x^2  y^2, {x, px, y, py}]

enter image description here

E. Chan-López
  • 23,117
  • 3
  • 21
  • 44
  • Thanks for the answer! I didn't know the jargon either. So even functions can be scalar or tensor. – codebpr Mar 04 '24 at 13:21
  • 1
    @codebpr This is what we can submit together to the repository :) – E. Chan-López Mar 04 '24 at 13:26
  • @codebpr I'm going to document it and co-author it with you and another colleague. Next, I'll send something else with Alex. – E. Chan-López Mar 04 '24 at 13:28
  • 1
    I have also edited the one. you wish to use, let me post that too, as an answer to that question. – codebpr Mar 04 '24 at 13:28
  • Also, please see this related question I asked today based on your first interactive algorithm. I think it would be an excellent addition to your resource function if you also enable the user to pick a suitable Method for NDSolve as you can see that sensitive systems with small positive maximal Lyapunov exponent show better results in some than others. – codebpr Mar 05 '24 at 13:39
  • @codebpr In fact, not only the method in NDSolve, I also need to include an argument for the events in WhenEvent, since not all events are simple conditions like in the examples I handle. This will take some time to do in great detail, as I need to test these changes to make the documentation more instructive. I'll go in steps, as I would like to submit this resource function first before submitting an update to ClickPoincarePlot2D. – E. Chan-López Mar 05 '24 at 13:58
  • 1
    @codebpr There are other things I want to add, but it seems like a lot for a resource function. Currently, I am writing a project to carry out a postdoctoral position in my country and this will make my progress in updating ClickPoincarePlot2D slow, but it is certain that I will finish it. Perhaps, and with good active collaboration, this expanded work will lead to a publication, or also to build a Paclet that serves as a laboratory for the analysis of Poincaré sections. – E. Chan-López Mar 05 '24 at 14:07
  • 1
    Same for me, I am also in the process of writing my PhD thesis. If you don't mind, can you share your email so that we can communicate efficiently on this subject with elaborate discussions so that we may be able to achieve something similar to what Professor Leo C. Stein of the University of Mississippi and his team did in JavaScript. – codebpr Mar 05 '24 at 15:18
  • @codebpr The ScalarPureFunction has been submitted to the repository. – E. Chan-López Mar 08 '24 at 03:17
  • 1
    Congratulations! I hope it will be published soon :) – codebpr Mar 08 '24 at 04:14
  • 1
    @codebpr You are a co-author (Bhaskar Shukla) and so is Alex. I'll let you know as soon as it's published. ;) – E. Chan-López Mar 08 '24 at 04:22
  • 1
    Great news to start the day with! Thank you :) – codebpr Mar 08 '24 at 04:23
  • @codebpr The work is done! ScalarPureFunction – E. Chan-López Mar 20 '24 at 22:05
  • 1
    Wow! Many congratulations to you and all other collaborators :) – codebpr Mar 21 '24 at 04:05
  • 1
    @codebpr Congratulations to you too! We already have a first collaboration. Let's go for more. – E. Chan-López Mar 21 '24 at 04:16
  • 1
    Yes, definitely! I am also working on improving the Poincare section function. – codebpr Mar 21 '24 at 04:17
  • 1
    @codebpr I'm trying to move forward with updating that function (Poincare), but I'm wondering which topic to address first. We must add events to the arguments so that we can address more complicated systems in that sense, such as systems that include pendulums. With so many arguments, we approach the need to create an interface like that of Leo C. Stein. I have stopped a little because I advanced on a function for Hamilton equations that includes an analysis of the regularity of Lagrangians. The idea is that we can build the Dynamic Analysis Paclet. – E. Chan-López Mar 21 '24 at 04:30