       Re: Programmatically creating functions of many variables

• To: mathgroup at smc.vnet.net
• Subject: [mg113683] Re: Programmatically creating functions of many variables
• From: Leonid Shifrin <lshifr at gmail.com>
• Date: Sun, 7 Nov 2010 05:13:07 -0500 (EST)

```Hi Yaroslav,

Unfortunately I don't quite follow the specific problem you stated - if you
start
with an adjacency matrix, I don't quite see how you can get improper
labeling -
if you have ones on the diagonal that would just mean self-loops.

Regarding a general question of run-time generation of multivariate
functions,
this is rarely needed since in most such cases all arguments have similar
nature
and can then be combined into a list, so that you have a function of a
single argument
being a list. If you still want to do this, here are a few ways (I have no
idea whether
or not they are typical - these are what I use sometimes).

I will use a model problem of a function which takes any nonzero number of
integer
arguments and checks that none of them is a multiple of some fixed number.
One way to
generate such a function is to create a pattern-based definition for some
symbol
and then return that symbol:

In:=
Clear[noDivisorCheck];
noDivisorCheck[n_Integer] :=
Module[{checkF},
checkF[args__Integer] := And @@ Thread[Mod[{args}, n] != 0];
checkF]

In:= fn = noDivisorCheck

Out= checkF\$110

In:= fn[1, 2, 3, 4]

Out= True

In:= fn[1, 2, 3, 4, 5]

Out= False

You can also do this using a pure function, but then we have to use the
undocumented
form Function[Null, body], which can accept any number of arguments:

In:=
Clear[noDivisorCheckPF];
noDivisorCheckPF[n_Integer] :=
Function[Null, And @@ Thread[Mod[{##}, n] != 0]];

In:= fnPF = noDivisorCheckPF

Out= Function[Null, And @@ Thread[Mod[{##1}, 5] != 0]]

In:= fnPF [1, 2, 3, 4]

Out= True

In:= fnPF [1, 2, 3, 4, 5]

Out= False

Note that these two methods have a couple of subtle differences in the way
they work.
One of them is that if you copiously produce functions with the first
method, these symbols are not garbage-collected unless you explicitly Remove
them,
so you may eventually produce a lot of garbage in your working context. This
problem
does not exist for pure functions.

If you know the number of arguments at the moment when you create a
function,
and it will be fixed, you can do something similar to what you suggested
(can not
use subscripts though):

In:=
Clear[noDivisorCheckPFFixedArgNum]
noDivisorCheckPFFixedArgNum[n_Integer, argnum_Integer?Positive] :=
Block[{x},
With[{args  = ToExpression["x" <> ToString@#] & /@ Range[argnum]},
Function @@ Hold[args, And @@ Thread[Mod[args, n] != 0]]]]

Block[{x},...] was used to make sure that we don't capture any global value
that <x>
may have, at the moment when we create our function (This could have been
accomplished
also by using Hold wrappers on the individual x variables, but that would be
more code).
Hold was used to prevent the premature evaluation of the body of the
function.

In:= fn4 = noDivisorCheckPFFixedArgNum[5, 4]

Out= Function[{x1, x2, x3, x4},
And @@ Thread[Mod[{x1, x2, x3, x4}, 5] != 0]]

In:= fn4[1, 2, 3, 4]

Out= True

In this method, however, we have to create a new function for a
different number of arguments, so it is less flexible in that sense:

In:= fn5 = noDivisorCheckPFFixedArgNum[5, 5]

Out= Function[{x1, x2, x3, x4, x5},
And @@ Thread[Mod[{x1, x2, x3, x4, x5}, 5] != 0]]

In:= fn5[1, 2, 3, 4, 5]

Out= False

Hope this helps.

Regards,
Leonid

On Sat, Nov 6, 2010 at 1:01 PM, Yaroslav Bulatov <yaroslavvb at gmail.com>wrote:

> Suppose I have a graph, and I'd like to create a function which checks
> whether given assignment of nodes is a proper labeling -- ie, no two
> adjacent nodes get the same number. One could do something like the
> following, but that gives Part warnings. Is there a preferred
> approach?
>
> graph = GraphData[{"Grid", {2, 2}}, "AdjacencyMatrix"] // Normal;
> f = Function @@ {{x}, And @@ (x[[First[#]]] != x[[Last[#]]] & /@
> Position[graph, 1])}
>
> This is actually a problem that I periodically come across. Part
> approach causes warnings meanwhile something like Function @@
> {Subscript[x,#]&/@Range[n], ...} doesn't work. What are typical ways
> of generating multivariate functions automatically?
>
> ----
> Yaroslav
> http://stackoverflow.com/users/419116/yaroslav-bulatov
>
>

```

• Prev by Date: Re: MathOO: Adding Object Orientation to Mathematica
• Next by Date: Re: Balance point of a solid
• Previous by thread: Programmatically creating functions of many variables
• Next by thread: FFT in mathematica