Appending _?NumericQ automatically to every variable of a function in the definition
If you want to name your variables, but don't want to repeat the pattern test ?NumericQ
for each variable, you can use PatternSequence
:
f[PatternSequence[a1_, a2_, a3_, a4_, a5_]?NumericQ] := {a1, a1+a4, a2+a3, a5}
Check:
f[1,2,3,4,5]
f[1,2,a,4,5]
{1, 5, 5, 5}
f[1, 2, a, 4, 5]
Actually I only want to define a function with many variables as
obj[a1_?NumericQ,a2_?NumericQ,...,a500_?NumericQ]
In this case I think it would be much simpler to use something like
obj[vars__?NumericQ /; Length[{vars}] === 5] := Module[
{a1, a2, a3, a4, a5},
{a1, a2, a3, a4, a5} = {vars};
(* do something useful here, like *)
Total @ {a1, a2, a3, a4, a5}
]
Now obj
behave exactly as you want, but you don't have to do any voodoo with creating your definition.
In[11]:= obj[1, 2, 3, 4, 5]
Out[11]= 15
In[12]:= obj[1, 2, 3, a + 4, 5]
Out[12]= obj[1, 2, 3, 4 + a, 5]
What about this?
With[{
lhs = ReplacePart[
Table[
PatternTest[
Pattern[Evaluate[Symbol["a" <> IntegerString[k]]], Blank[]],
NumericQ
],
{k, 1, 500}
],
0 -> obj
],
rhs = 1
},
SetDelayed[lhs, rhs]
]
The list of variables can be obtained with
Table[Symbol["a" <> IntegerString[k]], {k, 1, 500}]
But on the long run, a better strategy might be to define your function like so:
obj[a_?(VectorQ[#,NumericQ]&)] := ...
and to refer to the entries of a
with Indexed[a,i]
on the right hand side. (And yes, functions like FindMinimum
and FindRoot
can be convinced to work such functions.)