I am having a problem with pattern testing on variables during function definition

nfun[M : Repeated[_?(test1&&test2||test3..)&, {10}]]:= N@(Norm@(Sin[#] & /@ M))

I want to have a few tests on the vectors M that I want to feed nfun. One example that does not work if I want to test if M has Integer entries using Repeated is the following.

nfun[M : Repeated[_?IntegerQ, {10}]]:= N@(Norm@(Sin[#] & /@ M))

Here goes another filed trial with the same aim.

nfun[M_?((VectorQ[#, IntegerQ]) && (Length[#] == 10)) &]:= N@(Norm@(Sin[#] & /@ M))

2 Answers 2

nfun[M : Repeated[_IntegerQ, {10}]]:= N@(Norm@(Sin[#] & /@ M))

This does not work because _IntegerQ is testing an expression for the explicit head IntegerQ rather than Integer. Use _Integer or generically _?test.

For applying a series of tests I recommend:

f[M : Repeated[_Integer, {10}]] /; test1[M] && test2[M] || test[M] := {{M}}

Okay, I see that this is not identical to what you were constructing because of the difference between PatternTest and Condition. If your aim is to test every element separately it is usually cleanest to establish a single test function and use _?test. For example:

test = # < 8 && EvenQ[#] || PrimeQ[#] &;

f[M : Repeated[_?test, {10}]] := {{M}}
  • $\begingroup$ However nfun[M : Repeated[_Integer, {10}]] :=N@(Norm@(Sin[#] & /@ M)) does not work either if you try nfun[Range[10]] and same for the f you defined with the test. Try f[M : Repeated[_?test, {4}]] := {{M}}; test[#] & /@ {2, 4, 6, 13} which gives all true. But f[{2, 4, 6, 13}] does not evaluate! $\endgroup$ Jun 20, 2012 at 15:54
  • 1
    $\begingroup$ +1 for a separate function - I agree that it is the cleanest way. $\endgroup$ Jun 20, 2012 at 16:08
  • $\begingroup$ @PlatoManiac You're mixing your input types. Try : nfun @@ Range[10] or change you definition to account for List. $\endgroup$
    – Mr.Wizard
    Jun 20, 2012 at 16:10
  • $\begingroup$ @Mr.Wizard I thought Repeated will take care of a list with length 10. I saw your answer (stackoverflow.com/questions/8255210/…) before I posed my question. How can I use something like ListQ in this context of Repeated so that nfun[Range[10]] works. I am so dumb when it comes to use this fancy patterns :( $\endgroup$ Jun 20, 2012 at 16:56
  • $\begingroup$ @PlatoManiac don't say you're dumb, this stuff gets complicated! In this case you need to think of Repeated as being a bare "sequence" of elements like 1, 2, 3 without a head, therefore you need { Repeated[ stuff ] } if you want to match a List with repeated elements inside it. This is similar to: f[ x__ ] := versus f[ {x__} ] := $\endgroup$
    – Mr.Wizard
    Jun 20, 2012 at 17:31

I'd have done nfun[M : {__Integer}] /; Length[M] == 10 := N@(Norm@(Sin[#] & /@ M)) myself, at least for your specific example.


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.