4
$\begingroup$

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?

$\endgroup$
6
  • $\begingroup$ hPure = H[#[[2]], #[[4]], #[[1]], #[[3]]] & ? $\endgroup$
    – Domen
    Mar 4 at 8:18
  • $\begingroup$ 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? $\endgroup$
    – Domen
    Mar 4 at 8:27
  • $\begingroup$ @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. $\endgroup$
    – codebpr
    Mar 4 at 9:06
  • $\begingroup$ 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. $\endgroup$
    – Domen
    Mar 4 at 9:20
  • 3
    $\begingroup$ 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. $\endgroup$
    – bmf
    Mar 4 at 9:22

3 Answers 3

5
$\begingroup$

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[#]&, ...]
$\endgroup$
1
  • $\begingroup$ Thanks! This would be the minimal way to save my time. $\endgroup$
    – codebpr
    Mar 4 at 12:29
4
$\begingroup$

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]]
$\endgroup$
3
$\begingroup$

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

$\endgroup$
18
  • 1
    $\begingroup$ @codebpr This is what we can submit together to the repository :) $\endgroup$ Mar 4 at 13:26
  • 1
    $\begingroup$ I have also edited the one. you wish to use, let me post that too, as an answer to that question. $\endgroup$
    – codebpr
    Mar 4 at 13:28
  • 1
    $\begingroup$ @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. $\endgroup$ Mar 5 at 14:07
  • 1
    $\begingroup$ 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. $\endgroup$
    – codebpr
    Mar 5 at 15:18
  • 1
    $\begingroup$ Congratulations! I hope it will be published soon :) $\endgroup$
    – codebpr
    Mar 8 at 4:14

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.