I am trying to keep an ordered list of matrices where the ordering is given by the absolute value of the determinant.
To do this I thought about using the SortedKeyList object in the sortedcontainers package. My code is the following:
import numpy as np
import numpy.linalg as la
from sortedcontainers import SortedKeyList
def random_mat(n):
return np.random.randint(0,5,n*n)
def abs_det(M):
n = np.int(np.sqrt(len(M)))
return np.abs(la.det(M.reshape((n,n)))
L = SortedKeyList([random_mat(3): i in range(10)], key=abs_det)
# So far this doesn't give me any issues. Updating the list is the problem:
M = np.array([0,1,2,1,0,2,2,1,0])
L.update(M) #This gives me an error
The error appears in the function abs_det, it says that it cannot take the length of an integer (numpy.int32), I suspect that when comparing arrays the sorted list is not taking the array as a whole but using the key function entrywise. Originally I tried to use the arrays as matrices with a shape (n,n) but when including them in the sorted list the shape would be lost and they were stored as arrays causing other problems when trying to compare them.
A sorted dictionary would not solve the problem as I am interested in taking ranges of the list.
What would be a way to keep a sorted list of matrices ordered by the absolute value of their determinant? Perhaps there is another implementation in Python of a sorted list that can deal with these sort of objects?
SortedKeyList.update is expecting an iterable, so it iterates over all the single integers in M and adds each one to the sorted container.
From the docstring in sortedlist.py
def update(self, iterable):
"""Update sorted list by adding all values from `iterable`.
It appears to work as you intended if you change that line to
L.update([M])
The method for adding a single item is add (thanks Kelly Bundy)
L.add(M)