# Revision history [back]

The question creates a very complicated dictionary, so complicated that even the keys are not easily accessible.

In the following code, i will also define a matrix K, and an n for my taste, in the same time using exact objects.

n = 3
K = matrix( ZZ, 3, 3, [ 1,2,1,2,1,2,1,2,1 ] )

import itertools
W = itertools.product( [0,1], repeat = n )
preimages = {}

for w in W:
w = vector(w)
w = w.row()
v = w.transpose()
u = w * K * v
u.set_immutable()
if u in preimages:
preimages[u].append(w)
else:
preimages[u] = [w]

keys = preimages.keys()
for key in keys:
print key, type(key), preimages[ key ]

# trying to get the value for the MATRIX [6], which is ("convinced" to be) a key...
m = matrix( ZZ, 1, 1, [6,] )
m.set_immutable()
print "preimages of [6,] is:", preimages[ m ]


This gives:

[0] <type 'sage.matrix.matrix_integer_dense.Matrix_integer_dense'> [[0 0 0]]
[1] <type 'sage.matrix.matrix_integer_dense.Matrix_integer_dense'> [[0 0 1], [0 1 0], [1 0 0]]
[13] <type 'sage.matrix.matrix_integer_dense.Matrix_integer_dense'> [[1 1 1]]
[6] <type 'sage.matrix.matrix_integer_dense.Matrix_integer_dense'> [[0 1 1], [1 1 0]]
[4] <type 'sage.matrix.matrix_integer_dense.Matrix_integer_dense'> [[1 0 1]]
preimages of [6,] is: [[0 1 1], [1 1 0]]


Note:

There are many other better ways to build versions of the above preimages dictionary. For instance:

n = 3
K = matrix( ZZ, 3, 3, [ 1,2,1,2,1,2,1,2,1 ] )

V = [ vector( c )
for c in cartesian_product( [ [ ZZ(0), ZZ(1) ] for _ in range(n) ] ) ]

def f( v ):
return ( v.row() * K * v.column() )[0,0]

f_values = list( set( [ f(v) for v in V ] ) )
preimages = dict( [ ( val, [ v for v in V if f(v) == val ] )
for val in f_values ] )


The generated dictionary is:

sage: import pprint
sage: pprint.pprint( preimages )
{0: [(0, 0, 0)],
1: [(0, 0, 1), (0, 1, 0), (1, 0, 0)],
4: [(1, 0, 1)],
6: [(0, 1, 1), (1, 1, 0)],
13: [(1, 1, 1)]}