ASKSAGE: Sage Q&A Forum - RSS feedhttps://ask.sagemath.org/questions/Q&A Forum for SageenCopyright Sage, 2010. Some rights reserved under creative commons license.Fri, 28 Oct 2022 21:26:56 +0200Forming unique collections of matriceshttps://ask.sagemath.org/question/64630/forming-unique-collections-of-matrices/I am facing following two similar kind of problems:
Problem(1) Suppose I have the following code:
A=matrix(2,2,[1,1,1,1])
B=matrix(2,2,[2,2,2,2])
C=matrix(2,2,[3,3,3,3])
D=matrix(2,2,[4,4,4,4])
L1=[A,B,C]
L2=[C,B,A]
L3=[A,C,D]
show(L1,L2,L3)
Then in the output I want L1 and L3 only, as L1 and L2 contain same matrices.
Problem(2): Now suppose we have the following code:
P=matrix(2,2,[5,5,5,5])
Q=matrix(2,2,[6,6,6,6])
R=matrix(2,2,[7,7,7,7])
S=matrix(2,2,[8,8,8,8])
T1=[P,P,Q]
T2=[Q,P,P]
T3=[P,R,S]
show(T1,T2,T3)
Here also, in the output I want T1 and T3 only, as T1 and T2 contain same matrices. Note that I want T1 as it is, that is, P should be there twice.Wed, 26 Oct 2022 18:51:02 +0200https://ask.sagemath.org/question/64630/forming-unique-collections-of-matrices/Answer by John Palmieri for <p>I am facing following two similar kind of problems:</p>
<p>Problem(1) Suppose I have the following code:</p>
<pre><code> A=matrix(2,2,[1,1,1,1])
B=matrix(2,2,[2,2,2,2])
C=matrix(2,2,[3,3,3,3])
D=matrix(2,2,[4,4,4,4])
L1=[A,B,C]
L2=[C,B,A]
L3=[A,C,D]
show(L1,L2,L3)
</code></pre>
<p>Then in the output I want L1 and L3 only, as L1 and L2 contain same matrices.</p>
<p>Problem(2): Now suppose we have the following code:</p>
<pre><code>P=matrix(2,2,[5,5,5,5])
Q=matrix(2,2,[6,6,6,6])
R=matrix(2,2,[7,7,7,7])
S=matrix(2,2,[8,8,8,8])
T1=[P,P,Q]
T2=[Q,P,P]
T3=[P,R,S]
show(T1,T2,T3)
</code></pre>
<p>Here also, in the output I want T1 and T3 only, as T1 and T2 contain same matrices. Note that I want T1 as it is, that is, P should be there twice.</p>
https://ask.sagemath.org/question/64630/forming-unique-collections-of-matrices/?answer=64633#post-id-64633The short answer is to use sets. The longer answer involves some technical details: in Sage, matrices are "mutable" (see https://doc.sagemath.org/html/en/reference/matrices/sage/matrix/matrix0.html?highlight=set_immutable#sage.matrix.matrix0.Matrix.set_immutable for some details), and mutable things can't be elements of sets. So you can do this:
def immutable_copy(mat): # could use a shorter name
"""
Return a copy of matrix ``mat`` which is immutable.
"""
return matrix(mat, immutable=True)
Then given your lists `L1`, `L2`, `L3`, you can test this:
set(immutable_copy(mat) for mat in L1) == set(immutable_copy(mat) for mat in L2)
It will be `True` for L1 and L2, false for other pairs. So you could, for example, do this:
answer = [] # what you actually want to print
seen = [] # sets you've seen so far
for L in [L1, L2, L3]:
S = set(immutable_copy(mat) for mat in L)
if S not in seen:
answer.append(L)
seen.append(S)
show(*answer)Wed, 26 Oct 2022 20:15:54 +0200https://ask.sagemath.org/question/64630/forming-unique-collections-of-matrices/?answer=64633#post-id-64633Comment by mak3521 for <p>The short answer is to use sets. The longer answer involves some technical details: in Sage, matrices are "mutable" (see <a href="https://doc.sagemath.org/html/en/reference/matrices/sage/matrix/matrix0.html?highlight=set_immutable#sage.matrix.matrix0.Matrix.set_immutable">https://doc.sagemath.org/html/en/refe...</a> for some details), and mutable things can't be elements of sets. So you can do this:</p>
<pre><code>def immutable_copy(mat): # could use a shorter name
"""
Return a copy of matrix ``mat`` which is immutable.
"""
return matrix(mat, immutable=True)
</code></pre>
<p>Then given your lists <code>L1</code>, <code>L2</code>, <code>L3</code>, you can test this:</p>
<pre><code>set(immutable_copy(mat) for mat in L1) == set(immutable_copy(mat) for mat in L2)
</code></pre>
<p>It will be <code>True</code> for L1 and L2, false for other pairs. So you could, for example, do this:</p>
<pre><code>answer = [] # what you actually want to print
seen = [] # sets you've seen so far
for L in [L1, L2, L3]:
S = set(immutable_copy(mat) for mat in L)
if S not in seen:
answer.append(L)
seen.append(S)
show(*answer)
</code></pre>
https://ask.sagemath.org/question/64630/forming-unique-collections-of-matrices/?comment=64678#post-id-64678Yes, this code is without incorporating your idea. I had incorporated your idea in this code, but there was no change in the output. That means I am making some mistake somewhere. So, wanted to know how to exactly do it. But I think, I should not trouble you further, as you have already helped a lot and given important inputs. Now, I also need to exercise my mind , only then will I learn and explore the things. Thanks for your time and patience.Fri, 28 Oct 2022 21:26:56 +0200https://ask.sagemath.org/question/64630/forming-unique-collections-of-matrices/?comment=64678#post-id-64678Comment by John Palmieri for <p>The short answer is to use sets. The longer answer involves some technical details: in Sage, matrices are "mutable" (see <a href="https://doc.sagemath.org/html/en/reference/matrices/sage/matrix/matrix0.html?highlight=set_immutable#sage.matrix.matrix0.Matrix.set_immutable">https://doc.sagemath.org/html/en/refe...</a> for some details), and mutable things can't be elements of sets. So you can do this:</p>
<pre><code>def immutable_copy(mat): # could use a shorter name
"""
Return a copy of matrix ``mat`` which is immutable.
"""
return matrix(mat, immutable=True)
</code></pre>
<p>Then given your lists <code>L1</code>, <code>L2</code>, <code>L3</code>, you can test this:</p>
<pre><code>set(immutable_copy(mat) for mat in L1) == set(immutable_copy(mat) for mat in L2)
</code></pre>
<p>It will be <code>True</code> for L1 and L2, false for other pairs. So you could, for example, do this:</p>
<pre><code>answer = [] # what you actually want to print
seen = [] # sets you've seen so far
for L in [L1, L2, L3]:
S = set(immutable_copy(mat) for mat in L)
if S not in seen:
answer.append(L)
seen.append(S)
show(*answer)
</code></pre>
https://ask.sagemath.org/question/64630/forming-unique-collections-of-matrices/?comment=64671#post-id-64671First, your original question was about comparing lists of matrices, and second, my main suggestion was to use `set` (or `Set`). This new code is not obviously related to either of those. Third, when I run your code, I appear to get unique triples of matrices, so I don't even know what you're asking anymore.Fri, 28 Oct 2022 17:15:52 +0200https://ask.sagemath.org/question/64630/forming-unique-collections-of-matrices/?comment=64671#post-id-64671Comment by John Palmieri for <p>The short answer is to use sets. The longer answer involves some technical details: in Sage, matrices are "mutable" (see <a href="https://doc.sagemath.org/html/en/reference/matrices/sage/matrix/matrix0.html?highlight=set_immutable#sage.matrix.matrix0.Matrix.set_immutable">https://doc.sagemath.org/html/en/refe...</a> for some details), and mutable things can't be elements of sets. So you can do this:</p>
<pre><code>def immutable_copy(mat): # could use a shorter name
"""
Return a copy of matrix ``mat`` which is immutable.
"""
return matrix(mat, immutable=True)
</code></pre>
<p>Then given your lists <code>L1</code>, <code>L2</code>, <code>L3</code>, you can test this:</p>
<pre><code>set(immutable_copy(mat) for mat in L1) == set(immutable_copy(mat) for mat in L2)
</code></pre>
<p>It will be <code>True</code> for L1 and L2, false for other pairs. So you could, for example, do this:</p>
<pre><code>answer = [] # what you actually want to print
seen = [] # sets you've seen so far
for L in [L1, L2, L3]:
S = set(immutable_copy(mat) for mat in L)
if S not in seen:
answer.append(L)
seen.append(S)
show(*answer)
</code></pre>
https://ask.sagemath.org/question/64630/forming-unique-collections-of-matrices/?comment=64676#post-id-64676Alternatively, replace your loops by using Python's itertools module: https://docs.python.org/3/library/itertools.html#itertools.combinations. So `import itertools` and then `for triple in itertools.combinations(MAT, 3): ...`. But again, this is pretty far from what you asked about in your question; it should be a separate question.Fri, 28 Oct 2022 20:04:40 +0200https://ask.sagemath.org/question/64630/forming-unique-collections-of-matrices/?comment=64676#post-id-64676Comment by John Palmieri for <p>The short answer is to use sets. The longer answer involves some technical details: in Sage, matrices are "mutable" (see <a href="https://doc.sagemath.org/html/en/reference/matrices/sage/matrix/matrix0.html?highlight=set_immutable#sage.matrix.matrix0.Matrix.set_immutable">https://doc.sagemath.org/html/en/refe...</a> for some details), and mutable things can't be elements of sets. So you can do this:</p>
<pre><code>def immutable_copy(mat): # could use a shorter name
"""
Return a copy of matrix ``mat`` which is immutable.
"""
return matrix(mat, immutable=True)
</code></pre>
<p>Then given your lists <code>L1</code>, <code>L2</code>, <code>L3</code>, you can test this:</p>
<pre><code>set(immutable_copy(mat) for mat in L1) == set(immutable_copy(mat) for mat in L2)
</code></pre>
<p>It will be <code>True</code> for L1 and L2, false for other pairs. So you could, for example, do this:</p>
<pre><code>answer = [] # what you actually want to print
seen = [] # sets you've seen so far
for L in [L1, L2, L3]:
S = set(immutable_copy(mat) for mat in L)
if S not in seen:
answer.append(L)
seen.append(S)
show(*answer)
</code></pre>
https://ask.sagemath.org/question/64630/forming-unique-collections-of-matrices/?comment=64675#post-id-64675Your new code doesn't even try to remember what triples you've already seen, so how can it possibly be testing whether you are getting `(a,b,c)` and then later `(a,c,b)`? You can keep track by storing the ones seen so far, using `set` or `Set` so that order doesn't matter, and then compare a newly found triple to see if it's already been seen. In short, as I said at the very start: use sets.Fri, 28 Oct 2022 20:02:28 +0200https://ask.sagemath.org/question/64630/forming-unique-collections-of-matrices/?comment=64675#post-id-64675Comment by mak3521 for <p>The short answer is to use sets. The longer answer involves some technical details: in Sage, matrices are "mutable" (see <a href="https://doc.sagemath.org/html/en/reference/matrices/sage/matrix/matrix0.html?highlight=set_immutable#sage.matrix.matrix0.Matrix.set_immutable">https://doc.sagemath.org/html/en/refe...</a> for some details), and mutable things can't be elements of sets. So you can do this:</p>
<pre><code>def immutable_copy(mat): # could use a shorter name
"""
Return a copy of matrix ``mat`` which is immutable.
"""
return matrix(mat, immutable=True)
</code></pre>
<p>Then given your lists <code>L1</code>, <code>L2</code>, <code>L3</code>, you can test this:</p>
<pre><code>set(immutable_copy(mat) for mat in L1) == set(immutable_copy(mat) for mat in L2)
</code></pre>
<p>It will be <code>True</code> for L1 and L2, false for other pairs. So you could, for example, do this:</p>
<pre><code>answer = [] # what you actually want to print
seen = [] # sets you've seen so far
for L in [L1, L2, L3]:
S = set(immutable_copy(mat) for mat in L)
if S not in seen:
answer.append(L)
seen.append(S)
show(*answer)
</code></pre>
https://ask.sagemath.org/question/64630/forming-unique-collections-of-matrices/?comment=64673#post-id-64673Let me apologize , perhaps I have not presented the things clearly. Let me mention that in my question, L1 and L2 contained same matrices , so basically they are repetitions with only position of matrices changed. I wanted removal of such repetitions . And by your solution we got only L1 ,as wished for. In output of my code also the triplets for example at sl.no. 1 and 2 contain same matrices, so there are repetitions with only the position of matrices being changed. I want removal of such repetitions.Fri, 28 Oct 2022 18:42:52 +0200https://ask.sagemath.org/question/64630/forming-unique-collections-of-matrices/?comment=64673#post-id-64673Comment by mak3521 for <p>The short answer is to use sets. The longer answer involves some technical details: in Sage, matrices are "mutable" (see <a href="https://doc.sagemath.org/html/en/reference/matrices/sage/matrix/matrix0.html?highlight=set_immutable#sage.matrix.matrix0.Matrix.set_immutable">https://doc.sagemath.org/html/en/refe...</a> for some details), and mutable things can't be elements of sets. So you can do this:</p>
<pre><code>def immutable_copy(mat): # could use a shorter name
"""
Return a copy of matrix ``mat`` which is immutable.
"""
return matrix(mat, immutable=True)
</code></pre>
<p>Then given your lists <code>L1</code>, <code>L2</code>, <code>L3</code>, you can test this:</p>
<pre><code>set(immutable_copy(mat) for mat in L1) == set(immutable_copy(mat) for mat in L2)
</code></pre>
<p>It will be <code>True</code> for L1 and L2, false for other pairs. So you could, for example, do this:</p>
<pre><code>answer = [] # what you actually want to print
seen = [] # sets you've seen so far
for L in [L1, L2, L3]:
S = set(immutable_copy(mat) for mat in L)
if S not in seen:
answer.append(L)
seen.append(S)
show(*answer)
</code></pre>
https://ask.sagemath.org/question/64630/forming-unique-collections-of-matrices/?comment=64669#post-id-64669@John Palmieri : Oh no, there is no connection with the discussion between you two. Sorry, I should have mentioned (to avoid confusion) that my last comment was in continuation to my previous comment. The code in my last comment doesn't give unique combinations. I tried to implement your idea in it, but I think I am making some mistake somewhere , so wanted to know how to exactly incorporate your idea in the last code.Fri, 28 Oct 2022 13:37:11 +0200https://ask.sagemath.org/question/64630/forming-unique-collections-of-matrices/?comment=64669#post-id-64669Comment by John Palmieri for <p>The short answer is to use sets. The longer answer involves some technical details: in Sage, matrices are "mutable" (see <a href="https://doc.sagemath.org/html/en/reference/matrices/sage/matrix/matrix0.html?highlight=set_immutable#sage.matrix.matrix0.Matrix.set_immutable">https://doc.sagemath.org/html/en/refe...</a> for some details), and mutable things can't be elements of sets. So you can do this:</p>
<pre><code>def immutable_copy(mat): # could use a shorter name
"""
Return a copy of matrix ``mat`` which is immutable.
"""
return matrix(mat, immutable=True)
</code></pre>
<p>Then given your lists <code>L1</code>, <code>L2</code>, <code>L3</code>, you can test this:</p>
<pre><code>set(immutable_copy(mat) for mat in L1) == set(immutable_copy(mat) for mat in L2)
</code></pre>
<p>It will be <code>True</code> for L1 and L2, false for other pairs. So you could, for example, do this:</p>
<pre><code>answer = [] # what you actually want to print
seen = [] # sets you've seen so far
for L in [L1, L2, L3]:
S = set(immutable_copy(mat) for mat in L)
if S not in seen:
answer.append(L)
seen.append(S)
show(*answer)
</code></pre>
https://ask.sagemath.org/question/64630/forming-unique-collections-of-matrices/?comment=64663#post-id-64663@mak3521: what is the connection between your recent comment and the rest of the discussion here?Fri, 28 Oct 2022 08:13:44 +0200https://ask.sagemath.org/question/64630/forming-unique-collections-of-matrices/?comment=64663#post-id-64663Comment by mak3521 for <p>The short answer is to use sets. The longer answer involves some technical details: in Sage, matrices are "mutable" (see <a href="https://doc.sagemath.org/html/en/reference/matrices/sage/matrix/matrix0.html?highlight=set_immutable#sage.matrix.matrix0.Matrix.set_immutable">https://doc.sagemath.org/html/en/refe...</a> for some details), and mutable things can't be elements of sets. So you can do this:</p>
<pre><code>def immutable_copy(mat): # could use a shorter name
"""
Return a copy of matrix ``mat`` which is immutable.
"""
return matrix(mat, immutable=True)
</code></pre>
<p>Then given your lists <code>L1</code>, <code>L2</code>, <code>L3</code>, you can test this:</p>
<pre><code>set(immutable_copy(mat) for mat in L1) == set(immutable_copy(mat) for mat in L2)
</code></pre>
<p>It will be <code>True</code> for L1 and L2, false for other pairs. So you could, for example, do this:</p>
<pre><code>answer = [] # what you actually want to print
seen = [] # sets you've seen so far
for L in [L1, L2, L3]:
S = set(immutable_copy(mat) for mat in L)
if S not in seen:
answer.append(L)
seen.append(S)
show(*answer)
</code></pre>
https://ask.sagemath.org/question/64630/forming-unique-collections-of-matrices/?comment=64659#post-id-64659I tried to implement the idea in the following code(which gives all combinations of three unique 3rd order (-1,1) circulant matrices sum of whose squares equals a given circulant matrix) but could not. Kindly guide . Also, there might be a better way to write the code which I have written. Suggest those also.
The code is:
n=3
T=Tuples((-1,1),n)
X=matrix.circulant([1,-3,5]) # Given circulant matrix
MAT=[]
for a in T:
A=matrix.circulant(a)
MAT.append(A)
Counter=0
for a in MAT:
for b in MAT:
for c in MAT:
if ((a!=b and a!=c) and b!=c) and ((a^2)+(b^2)+(c^2)==X):
Counter+=1
show("(",Counter,").",(a,b,c))Fri, 28 Oct 2022 05:12:45 +0200https://ask.sagemath.org/question/64630/forming-unique-collections-of-matrices/?comment=64659#post-id-64659Comment by John Palmieri for <p>The short answer is to use sets. The longer answer involves some technical details: in Sage, matrices are "mutable" (see <a href="https://doc.sagemath.org/html/en/reference/matrices/sage/matrix/matrix0.html?highlight=set_immutable#sage.matrix.matrix0.Matrix.set_immutable">https://doc.sagemath.org/html/en/refe...</a> for some details), and mutable things can't be elements of sets. So you can do this:</p>
<pre><code>def immutable_copy(mat): # could use a shorter name
"""
Return a copy of matrix ``mat`` which is immutable.
"""
return matrix(mat, immutable=True)
</code></pre>
<p>Then given your lists <code>L1</code>, <code>L2</code>, <code>L3</code>, you can test this:</p>
<pre><code>set(immutable_copy(mat) for mat in L1) == set(immutable_copy(mat) for mat in L2)
</code></pre>
<p>It will be <code>True</code> for L1 and L2, false for other pairs. So you could, for example, do this:</p>
<pre><code>answer = [] # what you actually want to print
seen = [] # sets you've seen so far
for L in [L1, L2, L3]:
S = set(immutable_copy(mat) for mat in L)
if S not in seen:
answer.append(L)
seen.append(S)
show(*answer)
</code></pre>
https://ask.sagemath.org/question/64630/forming-unique-collections-of-matrices/?comment=64654#post-id-64654@Emmanuel Charpentier: maybe I'm missing something, but if I do `S1 = Set(L1)` and `S2 = Set(L2)`, then `S1 == S2` returns `False`. If I convert the matrices to being immutable, then it works the same as `set`, at least as far as this is concerned. So maybe I should have used `Set` instead?
`reduce` sounds good; can you provide details? It's not something I ever use myself, so I don't think of it.Thu, 27 Oct 2022 23:21:15 +0200https://ask.sagemath.org/question/64630/forming-unique-collections-of-matrices/?comment=64654#post-id-64654Comment by Emmanuel Charpentier for <p>The short answer is to use sets. The longer answer involves some technical details: in Sage, matrices are "mutable" (see <a href="https://doc.sagemath.org/html/en/reference/matrices/sage/matrix/matrix0.html?highlight=set_immutable#sage.matrix.matrix0.Matrix.set_immutable">https://doc.sagemath.org/html/en/refe...</a> for some details), and mutable things can't be elements of sets. So you can do this:</p>
<pre><code>def immutable_copy(mat): # could use a shorter name
"""
Return a copy of matrix ``mat`` which is immutable.
"""
return matrix(mat, immutable=True)
</code></pre>
<p>Then given your lists <code>L1</code>, <code>L2</code>, <code>L3</code>, you can test this:</p>
<pre><code>set(immutable_copy(mat) for mat in L1) == set(immutable_copy(mat) for mat in L2)
</code></pre>
<p>It will be <code>True</code> for L1 and L2, false for other pairs. So you could, for example, do this:</p>
<pre><code>answer = [] # what you actually want to print
seen = [] # sets you've seen so far
for L in [L1, L2, L3]:
S = set(immutable_copy(mat) for mat in L)
if S not in seen:
answer.append(L)
seen.append(S)
show(*answer)
</code></pre>
https://ask.sagemath.org/question/64630/forming-unique-collections-of-matrices/?comment=64652#post-id-64652@John Palmieri : Why not use `Sets` (with a capital `S`) ?
Also, why not use `reduce` ?Thu, 27 Oct 2022 22:40:39 +0200https://ask.sagemath.org/question/64630/forming-unique-collections-of-matrices/?comment=64652#post-id-64652Comment by mak3521 for <p>The short answer is to use sets. The longer answer involves some technical details: in Sage, matrices are "mutable" (see <a href="https://doc.sagemath.org/html/en/reference/matrices/sage/matrix/matrix0.html?highlight=set_immutable#sage.matrix.matrix0.Matrix.set_immutable">https://doc.sagemath.org/html/en/refe...</a> for some details), and mutable things can't be elements of sets. So you can do this:</p>
<pre><code>def immutable_copy(mat): # could use a shorter name
"""
Return a copy of matrix ``mat`` which is immutable.
"""
return matrix(mat, immutable=True)
</code></pre>
<p>Then given your lists <code>L1</code>, <code>L2</code>, <code>L3</code>, you can test this:</p>
<pre><code>set(immutable_copy(mat) for mat in L1) == set(immutable_copy(mat) for mat in L2)
</code></pre>
<p>It will be <code>True</code> for L1 and L2, false for other pairs. So you could, for example, do this:</p>
<pre><code>answer = [] # what you actually want to print
seen = [] # sets you've seen so far
for L in [L1, L2, L3]:
S = set(immutable_copy(mat) for mat in L)
if S not in seen:
answer.append(L)
seen.append(S)
show(*answer)
</code></pre>
https://ask.sagemath.org/question/64630/forming-unique-collections-of-matrices/?comment=64648#post-id-64648Okay.Thanks a lot. I had posed a general question to get an idea how to do such a thing. Now, I will see how to implement that idea in a code on which I am working. If there is any problem I will get back.Thu, 27 Oct 2022 20:31:00 +0200https://ask.sagemath.org/question/64630/forming-unique-collections-of-matrices/?comment=64648#post-id-64648