6
$\begingroup$

I have been playing a bit with the undocumented function

Experimental`CreateNumericalFunction

and I wanted to know if somebody found a way to make generated numerical functions listable.

Here is an example: I define two functions, f and fC

In[1]:=f = Experimental`CreateNumericalFunction[{x}, x^2, {}, {_Real},WorkingPrecision -> 30];

In[2]:=fC = Compile[{{x, _Real}}, x^2, RuntimeAttributes -> {Listable}];

The first function is not listable, while the second is:

In[3]:=f@Table[i, {i, 1, 10}]
Out[3]:=Experimental`NumericalFunction[{x}, x^2,"-NumericalFunctionData-"][{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}]

In[4]:=fC@Table[i, {i, 1, 10}]
Out[4]:={1., 4., 9., 16., 25., 36., 49., 64., 81., 100.}

Is there a way to make f also listable?

$\endgroup$
4
  • $\begingroup$ What even is Experimental`CreateNumericalFunction? $\endgroup$
    – QuantumDot
    Oct 5, 2019 at 4:12
  • 1
    $\begingroup$ Unless I am mistaken, Experimental`CreateNumericalFunction is the closest one can get to compiling a function with arbitrary precision. As far as I can tell, Compile for now only takes Real64 arguments... Something like Real128 is still not available (not sure it will ever be). $\endgroup$
    – user12588
    Oct 5, 2019 at 4:20
  • 2
    $\begingroup$ Strongly related: "How to work with Experimental`NumericalFunction?." $\endgroup$ Oct 6, 2019 at 12:44
  • $\begingroup$ One could always wrap it with a Listable function: fL = Function[x, f[x], Listable] $\endgroup$
    – Michael E2
    Oct 6, 2019 at 12:52

1 Answer 1

8
$\begingroup$

I do not know a way to make Experimental`NumericalFunction listable itself, but depending of your goals you can achieve the same behavior in several ways.

The simplest way is to create a proxy Symbol with Listable attribute:

ClearAll[f, fL]
SetAttributes[fL, Listable]
fL[x_] := f[x]
f = Experimental`CreateNumericalFunction[{x}, x^2, {}, {_}, WorkingPrecision -> 30];
fL@Table[i, {i, 1, 10}]
{1.`30., 4.`30., 9.`30., 16.`30., 25.`30., 36.`30., 49.`30., 64.`30., 81.`30., 100.`30.}

It is also possible to assign the Listable attribute directly to f:

ClearAll[f]
SetAttributes[f, Listable]
f[x_] = Block[{x},
  Experimental`CreateNumericalFunction[{x}, x^2, {}, {_Real}, WorkingPrecision -> 30][x]]
f@Table[i, {i, 1, 10}]
{1.`30., 4.`30., 9.`30., 16.`30., 25.`30., 36.`30., 49.`30., 64.`30., 81.`30., 100.`30.}

Instead of the attribute one can program listability via Map what can be even faster:

ClearAll[f]
f[l_List] := f /@ l;
f[x_] = Block[{x},
   Experimental`CreateNumericalFunction[{x}, x^2, {}, {_Real}, WorkingPrecision -> 30][x]];
f@Table[i, {i, 1, 10}]
{1.`30., 4.`30., 9.`30., 16.`30., 25.`30., 36.`30., 49.`30., 64.`30., 81.`30., 100.`30.}

Another way is to create a listable pure function:

ClearAll[f]
f = With[{f = Experimental`CreateNumericalFunction[{x}, x^2, {}, {_Real}, WorkingPrecision -> 30]},
         Function[x, f[x], Listable]];
f@Table[i, {i, 1, 10}]
{1.`30., 4.`30., 9.`30., 16.`30., 25.`30., 36.`30., 49.`30., 64.`30., 81.`30., 100.`30.}

Or you can Map f at level -1 (assuming that your input matrix contains only numbers and not expressions):

ClearAll[f]
f = Experimental`CreateNumericalFunction[{x}, x^2, {}, {_Real}, WorkingPrecision -> 30];
table = Table[i, {i, 1, 10}];
Map[f, table, {-1}]
{1.`30., 4.`30., 9.`30., 16.`30., 25.`30., 36.`30., 49.`30., 64.`30., 81.`30., 100.`30.}

Also it is possible to create a numerical function accepting a list of fixed length (but probably it isn't sufficient for you):

ClearAll[f]
f = Experimental`CreateNumericalFunction[{{x, {10}}}, x^2, {10}, WorkingPrecision -> 30];
f@Table[i, {i, 1, 10}]
{1.`30., 4.`30., 9.`30., 16.`30., 25.`30., 36.`30., 49.`30., 64.`30., 81.`30., 100.`30.}
$\endgroup$
1
  • $\begingroup$ Dear Alexey, in the end the best option for me was to use ``` Map[f,table,{-1}]``` Thanks for all your help! $\endgroup$
    – user12588
    Oct 7, 2019 at 13:22

Your Answer

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

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