1
$\begingroup$

I wish to make custom listable function (for 2D points) with the next behaviour:

myf[{x_, y_}] := {doSmth@x, doSmth@y};
pts = {{x1,y1},{x2,y2}, ...};  
myf[pts] === {myf[{x1,y1}], myf[{x2,y2}], ...}

I'm going to do huge calculations, and read this in documentation:

To apply a function to a vector, take advantage of Listable functions when possible

And there is example that Listable without Map works ~10 times faster.

But when I set

Attributes[myf] = {Listable}

I get

 myf[pts] === {{myf[x1], myf[y1]}, {myf[x2], myf[y2]}, ...}

which is not what is needed ((

$\endgroup$
5
  • 2
    $\begingroup$ Are you aware of this? $\endgroup$
    – user1066
    Oct 30, 2023 at 11:38
  • $\begingroup$ @user1066, Hmm,I should think it over, but I'm not going to use some packed arrays $\endgroup$
    – lesobrod
    Oct 30, 2023 at 11:46
  • 3
    $\begingroup$ And the behavior you want can be easily achieved with Compile, but to use Compile properly we need to know what's that doSmth, so please make the question more specific. $\endgroup$
    – xzczd
    Oct 30, 2023 at 11:58
  • 1
    $\begingroup$ One usual trick is to pack a pair of {xk, yk} as a complex number zk := xk + yk I, then define a Listable function to be used on {z1, z2, ...}. $\endgroup$
    – Silvia
    Oct 30, 2023 at 19:42
  • $\begingroup$ if myf is already listable, it will automatically map. for example: myf = (#+1)*2&; myf@{{1,2},{3,4}} $\endgroup$ Oct 31, 2023 at 18:31

2 Answers 2

2
$\begingroup$
pts = {{x1, y1}, {x2, y2}};

Just use Map:

Map[myf, pts]

{myf[{x1, y1}], myf[{x2, y2}]}

Or define

mf[x_] := Map[myf, x]

mf[pts]

{myf[{x1, y1}], myf[{x2, y2}]}

$\endgroup$
1
  • $\begingroup$ Thank you, maybe, but please look at edited question $\endgroup$
    – lesobrod
    Oct 30, 2023 at 11:19
1
$\begingroup$
$Version

(* "13.3.1 for Mac OS X ARM (64-bit) (July 24, 2023)" *)

ClearAll["Global`*"]

Rather than use the attribute Listable, define myf as

myf[x_?VectorQ] := doSmth /@ x;

myf[x_List] := myf /@ x

Then

pts = Array[{x[#], y[#]} &, 4]

(* {{x[1], y[1]}, {x[2], y[2]}, {x[3], y[3]}, {x[4], y[4]}} *)

myf[pts]

(* {{doSmth[x[1]], doSmth[y[1]]}, {doSmth[x[2]], 
  doSmth[y[2]]}, {doSmth[x[3]], doSmth[y[3]]}, {doSmth[x[4]], 
  doSmth[y[4]]}} *)
$\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.