Message Boards Message Boards

0
|
2598 Views
|
13 Replies
|
2 Total Likes
View groups...
Share
Share this post:

A function accepts multiple matrices arguments

Posted 1 year ago

See my following example:

In[87]:= f//ClearAll;
f[{m__?MatrixQ} | m__?MatrixQ, c_Matrix:{{}}, mod_Integer: 1]:={{m},c,mod}
f[{IdentityMatrix[2],IdentityMatrix[2]},IdentityMatrix[3]]
f[IdentityMatrix[2],IdentityMatrix[2],IdentityMatrix[3]]

Out[89]= f[{{{1, 0}, {0, 1}}, {{1, 0}, {0, 1}}}, {{1, 0, 0}, {0, 1, 
   0}, {0, 0, 1}}]

Out[90]= {{{{1, 0}, {0, 1}}, {{1, 0}, {0, 1}}, {{1, 0, 0}, {0, 1, 
    0}, {0, 0, 1}}}, {{}}, 1}

Why can't the first call work as expected?

Regards,
Zhao

POSTED BY: Hongyi Zhao
13 Replies

Your code has a typo. So you are asking the entire readership to locate a simple bug in your code. This is not acceptable practice, as such requests cheapen the value of the forum.

POSTED BY: Daniel Lichtblau
Posted 1 year ago

Daniel, I am not aware of any important typos in this thread so far. Please point it out.

POSTED BY: Hans Milton

Matrix --> MatrixQ.

POSTED BY: Daniel Lichtblau
Posted 1 year ago

I can't find the typo you said. In the OP, I used the following form:

c_Matrix:{{}}

POSTED BY: Hongyi Zhao
Posted 1 year ago

The pattern will only match if you pass an argument with head Matrix. It seems like you want arguments with head List. Your default value {{}} has head List. Unless you’re keeping us in the dark about some Matrix symbol that you’ve defined, it does seem like a typo.

POSTED BY: Eric Rimbey
Posted 1 year ago

Right, that looks like a typo. But it is not the source of the problem. Since correcting it does not change anything.

With typo:

In[33]:= f[{m__?MatrixQ} | m__?MatrixQ, c_Matrix : {{}}, mod_Integer : 1] := {{m}, c, mod}
In[34]:= f[{IdentityMatrix[2], IdentityMatrix[2]}, IdentityMatrix[3]]
Out[34]= f[{{{1, 0}, {0, 1}}, {{1, 0}, {0, 1}}}, {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}]

Typo fixed:

In[35]:= g[{m__?MatrixQ} | m__?MatrixQ, c_?MatrixQ : {{}}, mod_Integer : 1] := {{m}, c, mod}
In[36]:= g[{IdentityMatrix[2], IdentityMatrix[2]}, IdentityMatrix[3]]
Out[36]= g[{{{1, 0}, {0, 1}}, {{1, 0}, {0, 1}}}, {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}]
POSTED BY: Hans Milton

Thank you Hans, that's a fair point. Nonetheless I do not want this to become a forum for finding and fixing typos. That is for the poster to do. After which, problematic behavior can be presented here.

POSTED BY: Daniel Lichtblau
Posted 1 year ago

Thank you Hans,

It seems to be working very well:

In[319]:= g//ClearAll;
(*g[{m__?MatrixQ}|m__?MatrixQ,c_, mod_:1]:={{m},c,mod} /; MatrixQ[c]&&IntegerQ[mod]
You can also write the function with the c and mod conditions on the left hand side:*)

g[{m__?MatrixQ} | m__?MatrixQ, c_, mod_ : 1] /; MatrixQ[c] && IntegerQ[mod] := {{m}, c, mod}

g[{IdentityMatrix[2], IdentityMatrix[2]}]
g[IdentityMatrix[2], IdentityMatrix[2]]
g[IdentityMatrix[2], IdentityMatrix[2],IdentityMatrix[2]]
g[{IdentityMatrix[2], IdentityMatrix[2]}, IdentityMatrix[3]]
g[IdentityMatrix[2], IdentityMatrix[2], IdentityMatrix[3]]
g[{IdentityMatrix[2], IdentityMatrix[2]}, IdentityMatrix[3], 4.5]
g[{IdentityMatrix[2], IdentityMatrix[2]}, 5.7]

Out[321]= g[{{{1, 0}, {0, 1}}, {{1, 0}, {0, 1}}}]

Out[322]= {{{{1, 0}, {0, 1}}}, {{1, 0}, {0, 1}}, 1}

Out[323]= {{{{1, 0}, {0, 1}}, {{1, 0}, {0, 1}}}, {{1, 0}, {0, 1}}, 1}

Out[324]= {{{{1, 0}, {0, 1}}, {{1, 0}, {0, 1}}}, {{1, 0, 0}, {0, 1, 
   0}, {0, 0, 1}}, 1}

Out[325]= {{{{1, 0}, {0, 1}}, {{1, 0}, {0, 1}}}, {{1, 0, 0}, {0, 1, 
   0}, {0, 0, 1}}, 1}

Out[326]= g[{{{1, 0}, {0, 1}}, {{1, 0}, {0, 1}}}, {{1, 0, 0}, {0, 1, 
   0}, {0, 0, 1}}, 4.5]

Out[327]= g[{{{1, 0}, {0, 1}}, {{1, 0}, {0, 1}}}, 5.7]
POSTED BY: Hongyi Zhao
Posted 1 year ago

You can also write the function with the c and mod conditions on the lefthand side:

h[{m__?MatrixQ} | m__?MatrixQ, c_ : {{}}, mod_ : 1] /; MatrixQ[c] && IntegerQ[mod] := {{m}, c, mod}
POSTED BY: Hans Milton
Posted 1 year ago

Yes. Thanks a lot. This way works.

In[234]:= g//ClearAll;
g[{m__?MatrixQ}|m__?MatrixQ,c_:{{}},mod_:1]:={{m},c,mod} /; MatrixQ[c]&&IntegerQ[mod]

g[{IdentityMatrix[2], IdentityMatrix[2]}]
g[{IdentityMatrix[2], IdentityMatrix[2]}, IdentityMatrix[3]]
g[{IdentityMatrix[2], IdentityMatrix[2]}, IdentityMatrix[3], 4.5]
g[{IdentityMatrix[2], IdentityMatrix[2]}, 5.7]

Out[236]= {{{{1, 0}, {0, 1}}, {{1, 0}, {0, 1}}}, {{}}, 1}

Out[237]= {{{{1, 0}, {0, 1}}, {{1, 0}, {0, 1}}}, {{1, 0, 0}, {0, 1, 
   0}, {0, 0, 1}}, 1}

Out[238]= g[{{{1, 0}, {0, 1}}, {{1, 0}, {0, 1}}}, {{1, 0, 0}, {0, 1, 
   0}, {0, 0, 1}}, 4.5]

Out[239]= g[{{{1, 0}, {0, 1}}, {{1, 0}, {0, 1}}}, 5.7]

But how to encapsulate the checking types of arguments c and mod with modular programming?

Regards, Zhao

POSTED BY: Hongyi Zhao
Posted 1 year ago

Ok, try this method for checking types of arguments c and mod :

h[{m__?MatrixQ}|m__?MatrixQ,c_:{{}},mod_:1]:={{m},c,mod}/;MatrixQ[c]&&IntegerQ[mod]
POSTED BY: Hans Milton
Posted 1 year ago

In my case, c must be a matrix, so the following result is incorrect:

In[5]:=g[{IdentityMatrix[2], IdentityMatrix[2]}, 5.7]
Out[5]={{{{1, 0}, {0, 1}}, {{1, 0}, {0, 1}}}, 5.7, 1}
POSTED BY: Hongyi Zhao
Posted 1 year ago

Check this:

In[1]:= g[{m__?MatrixQ} | m__?MatrixQ, c_ : {{}}, mod_Integer : 1] := {{m}, c,mod}

In[2]:=g[{IdentityMatrix[2], IdentityMatrix[2]}]
Out[2]={{{{1, 0}, {0, 1}}, {{1, 0}, {0, 1}}}, {{}}, 1}

In[3]:=g[{IdentityMatrix[2], IdentityMatrix[2]}, IdentityMatrix[3]]
Out[3]={{{{1, 0}, {0, 1}}, {{1, 0}, {0, 1}}}, {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, 1}

In[4]:=g[{IdentityMatrix[2], IdentityMatrix[2]}, IdentityMatrix[3], 4.5]
Out[4]=g[{{{1, 0}, {0, 1}}, {{1, 0}, {0, 1}}}, {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, 4.5]

In[5]:=g[{IdentityMatrix[2], IdentityMatrix[2]}, 5.7]
Out[5]={{{{1, 0}, {0, 1}}, {{1, 0}, {0, 1}}}, 5.7, 1}
POSTED BY: Hans Milton
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract