[Date Index]
[Thread Index]
[Author Index]
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[1]:=
Clear[noDivisorCheck];
noDivisorCheck[n_Integer] :=
Module[{checkF},
checkF[args__Integer] := And @@ Thread[Mod[{args}, n] != 0];
checkF]
In[3]:= fn = noDivisorCheck[5]
Out[3]= checkF$110
In[4]:= fn[1, 2, 3, 4]
Out[4]= True
In[5]:= fn[1, 2, 3, 4, 5]
Out[5]= 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[6]:=
Clear[noDivisorCheckPF];
noDivisorCheckPF[n_Integer] :=
Function[Null, And @@ Thread[Mod[{##}, n] != 0]];
In[8]:= fnPF = noDivisorCheckPF[5]
Out[8]= Function[Null, And @@ Thread[Mod[{##1}, 5] != 0]]
In[9]:= fnPF [1, 2, 3, 4]
Out[9]= True
In[10]:= fnPF [1, 2, 3, 4, 5]
Out[10]= 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[11]:=
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[13]:= fn4 = noDivisorCheckPFFixedArgNum[5, 4]
Out[13]= Function[{x1, x2, x3, x4},
And @@ Thread[Mod[{x1, x2, x3, x4}, 5] != 0]]
In[14]:= fn4[1, 2, 3, 4]
Out[14]= 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[15]:= fn5 = noDivisorCheckPFFixedArgNum[5, 5]
Out[15]= Function[{x1, x2, x3, x4, x5},
And @@ Thread[Mod[{x1, x2, x3, x4, x5}, 5] != 0]]
In[16]:= fn5[1, 2, 3, 4, 5]
Out[16]= 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**
| |