From: guerom00 on
Hello all,

Here is a snippet of code:

MyArcTan := Function[{x, y},
Module[{result},
If[x == 0 && y == 0,
result = 0,
result = ArcTan[x, y]
];
result
]
];

In[725]:= Thread[MyArcTan[{-1, 0, 1}, 0]]

Out[725]= result$58407737

Somehow, when I thread my custom function MyArcTan[], it does not
execute the If[] test hence do not define the result...

How can I solve that ?

TIA

From: Bill Rowe on
On 7/30/10 at 6:56 AM, guerom00(a)gmail.com (guerom00) wrote:

>Here is a snippet of code:

>MyArcTan := Function[{x, y},
>Module[{result},
>If[x == 0 && y == 0,
>result = 0,
>result = ArcTan[x, y]
>];
>result
>]
>];

>In[725]:= Thread[MyArcTan[{-1, 0, 1}, 0]]

>Out[725]= result$58407737

>Somehow, when I thread my custom function MyArcTan[], it does not
>execute the If[] test hence do not define the result...

>How can I solve that ?

No, the problem isn't with Thread or If. The problem is related
to the way Module localizes variables. For this function, there
is no need for Module or the local variable result. Your
function can be more simply written as:

MyArcTan := Function[{x, y}, If[x == 0 && y == 0, 0, ArcTan[x, y]=
]];

or

MyArcTan[x_, y_}]:= If[x == 0 && y == 0, 0, ArcTan[x, y]]

with either of these you can do:

In[3]:= Thread[f[{-1, 0, 1}, 0]] /. f -> MyArcTan

Out[3]= {Pi, 0, 0}

or

In[4]:= MapThread[MyArcTan, {{-1, 0, 0}, {0, 0, 0}}]

Out[4]= {Pi, 0, 0}

to get the desired output.


From: Albert Retey on
Am 30.07.2010 12:56, schrieb guerom00:
> Hello all,
>
> Here is a snippet of code:
>
> MyArcTan := Function[{x, y},
> Module[{result},
> If[x == 0 && y == 0,
> result = 0,
> result = ArcTan[x, y]
> ];
> result
> ]
> ];
>
> In[725]:= Thread[MyArcTan[{-1, 0, 1}, 0]]
>
> Out[725]= result$58407737
>
> Somehow, when I thread my custom function MyArcTan[], it does not
> execute the If[] test hence do not define the result...

The problem is that Thread evaluates its argument and MyArcTan does
evaluate with whatever argument you give it, so Thread just ends up to
see the result$... and has nothing left to do. You can see this from
evaluating the argument only:

MyArcTan[{-1, 0, 1}, 0]

The following does help Thread to see what you intend in this case:

Thread[Unevaluated[MyArcTan[{-1, 0, 1}, 0]]]

Note that the SetDelayed (:=) and the Module are not causing anything
but overhead in your case, this should always give the same results:

MyArcTan = Function[{x, y}, If[x == 0 && y == 0, 0, ArcTan[x, y]]]

There are other possibilities to solve your problem, but it is not clear
which one would be the best without knowing more about what the big
picture is...

hth,

albert


From: Themis Matsoukas on
Here is a workaround:

Thread[f[{-1, 0, 1}, 0]] /. f -> MyArcTan
{\[Pi], 0, 0}

The problem is that Thread first evaluates and then threads (see ref/Thread under possible issues). To see what is going on, redefine your function in the simpler form:

MyArcTan2 := Function[{x, y}, If[x == 0 && y == 0, 0, ArcTan[x, y]]]

and execute

Thread[MyArcTan2[{-1, 0, 1}, 0]]
If[{-1, 0, 1} == 0, 0, ArcTan[{-1, 0, 1}, 0]]

This shows that instead of threading, Mathematica tries to evaluate the function with first argument {-1,0,1} and second argument 0, causing the If statement to choke. If at least one of these argument is not zero, then the If[] executes ArcTan[x, y], which is why the following still works:

Thread[MyArcTan[{-1, 0, 1}, 1]]
{(3 \[Pi])/4, \[Pi]/2, \[Pi]/4}

Themis