1
$\begingroup$

if I have an expression that contains a lot of symbolic elements and I would want to make it a function of the vector containing all the elements I've found a solution based on rule delayed:

vectelem = ToExpression["q" <> ToString[#]] &;
Mat = Table[vectelem@RandomInteger[{1, 30}], {i, 10}, {j, 10}];
qlist = Array[vectelem, 30];
Fmat[q_] := Mat /. Thread[qlist -> q]
Mat // MatrixForm
Fmat@Range[1, 30] // MatrixForm

{{q11, q23, q2, q27, q3, q14, q7, q12, q16, q7}, {q6, q27, q6, q29, 
  q2, q3, q27, q18, q20, q5}, {q4, q20, q17, q15, q17, q14, q26, q15, 
  q5, q18}, {q16, q10, q30, q10, q4, q13, q24, q6, q28, q21}, {q16, 
  q3, q17, q4, q12, q11, q12, q1, q20, q1}, {q9, q29, q7, q3, q20, 
  q23, q20, q10, q23, q5}, {q7, q28, q27, q4, q19, q26, q12, q30, q6, 
  q1}, {q9, q5, q16, q27, q5, q29, q12, q15, q4, q29}, {q26, q7, q16, 
  q18, q16, q3, q9, q21, q9, q23}, {q13, q9, q16, q6, q29, q6, q6, 
  q19, q21, q2}}

{{11, 23, 2, 27, 3, 14, 7, 12, 16, 7}, {6, 27, 6, 29, 2, 3, 27, 18, 
  20, 5}, {4, 20, 17, 15, 17, 14, 26, 15, 5, 18}, {16, 10, 30, 10, 4, 
  13, 24, 6, 28, 21}, {16, 3, 17, 4, 12, 11, 12, 1, 20, 1}, {9, 29, 7,
   3, 20, 23, 20, 10, 23, 5}, {7, 28, 27, 4, 19, 26, 12, 30, 6, 
  1}, {9, 5, 16, 27, 5, 29, 12, 15, 4, 29}, {26, 7, 16, 18, 16, 3, 9, 
  21, 9, 23}, {13, 9, 16, 6, 29, 6, 6, 19, 21, 2}}

Anyway I was asking myself if is there another way that avoid the use of set delayed, in order to get something like:

Fmat[{q1_,q2_, ... ,q30_}] = Mat;

Without writing all the 30 variables. Furthermore if I'd want all these variables being numeric ? Is there a way to not append ?NumericQ for each variable ?

$\endgroup$
3
  • 1
    $\begingroup$ does patterntest = PatternTest[Pattern@##, NumericQ] & @@@ Array[{Symbol["q" <> ToString@#], Blank[]} &, 30]; Fmat2[patterntest] = Mat; Fmat2@Range[30] // MatrixForm give what you need? $\endgroup$
    – kglr
    Commented Sep 9, 2021 at 11:40
  • 1
    $\begingroup$ or pattern = Pattern @@@ Array[{Symbol["q" <> ToString@#], Blank[]} &, 30]; Fmat3[p : pattern /; VectorQ[p, NumericQ]] = Mat; Fmat3@Range[30] // MatrixForm? $\endgroup$
    – kglr
    Commented Sep 9, 2021 at 11:45
  • $\begingroup$ @kglr you're the king of kings, thank you ! the first answer works pretty well, the second one gives me an error but I didn't investigate, it doesn't matter, thank you ! $\endgroup$ Commented Sep 10, 2021 at 17:01

1 Answer 1

1
$\begingroup$
SeedRandom[1]
Mat = Table[vectelem @ RandomInteger[{1, 30}], {i, 10}, {j, 10}];

You can use Pattern + Condition (/;) + VectorQ + NumericQ to define your argument pattern:

ClearAll[pattern, Fmat1]

pattern = p : Pattern @@@ Array[{Symbol["q" <> ToString@#], _} &, 30] /; 
   VectorQ[p, NumericQ]; 

Fmat1[pattern] = Mat;

If a list of symbols (such as your qlist) is already defined you can define pattern using

p : Thread[Pattern @@ {qlist, _}] /; VectorQ[p, NumericQ] 

% == pattern
True

Alternatively, you can use Pattern + PatternTest (?) + NumericQ

ClearAll[patterntest, Fmat2]

patterntest = Pattern[##]?NumericQ & @@@ Array[{Symbol["q" <> ToString @ #], _} &, 30]; 

Fmat2[patterntest] = Mat; 

If qlist is already defined you can define patterntest as:

Pattern[##]?NumericQ & @@@ Thread[{qlist, _}]

% == patterntest
True

Both give the same result as Fmat in OP:

Fmat1 @ Range @ 30 == Fmat2 @ Range @ 30 == Fmat @ Range @ 30
True
$\endgroup$

Your Answer

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

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