Could be less grief to use bitwise arithmetic, or imperative code like the other answers. (It turned out writing that roundrobin iterator was a world of pain. # But in the general case, N could be odd, and you need to handle one of the iterators being exhausted first and yielding None. # If you know N is even, you can get away with this. (N-1) and using these as row coords in a sparse-matrix (CSR) representation: from scipy.sparse import csr_matrixĬsr_matrix((*6, (, ))).toarray()Īnd for general N: csr_matrix((*N, (, list(range(N)) ))).toarray()Īnd a roundrobin iterator to generate the low/hi values: from itertools import chain, zip_longest, cycle One way is to the sequence 0,1,2,3,4,5 or. Introducing the more appropriate mid that uses flooring division even allows handling an uneven amount of numbers: > numbers = np.array() With this rather satisfying result: > numbers This should work just fine for your purposes vastly simplifying the array accesses by virtue of using slicing to a bit more of its potential: def permutation_matrix(N): This Stack Overflow question gives an interesting suggestion on how to do that. Once you realize that it becomes a matter of "interweaving the two halves of the identity matrix". Taking the indices of the elements as their identity you basically have the following "vector of vectors": The permutation matrix always has the same form if you look at it the right way. # return a list of elements in part 1 followed by elements in part 2 Not sure, but you can always cook something up. Halves of the same array without splitting them up? Is there an Pythonic way to implement two different functions on two Sure, numpy.roll does circular shifting: numpy.roll(, 4) = numpy.array() Is there an approach where I can shift the 1s without needing to Similarly, the memory requirements for storing these matrices in sparse format is O(n) instead of O(n^2). matrix-vector products can be computed in O(n) time instead of O(n^2). Multiplication with sparse matrices will be much faster: e.g. toarray()) to build a full matrix from this: e.g. # the following also works, if you are so inclined. # row and column indices - first even, then odd numbers in the latter ![]() Using its coo_matrix method we can build a matrix which contains given values at given indices.įrom here it's just a matter of building the right lists of indices. Since permutation matrices are rather sparse, the scipy.sparse library is helpful. Is there an approach where I can shift the 1s without needing to create a separate zeros array in memory?Īre there more efficient libraries than numpy for this? Is there an Pythonic way to implement two different functions on two halves of the same array without splitting them up? ![]() Is it necessary to split the array in two? Replace the row we are evaluating with our modified zeros array To summarise what I am doing to each matrix:Īt each row, identify where the 1 needs to be moved to, call it idxĬreate a separate zeros array, and insert a 1 into index idx I have a feeling that there are more efficient ways to do this. M = np.concatenate((I_even, I_odd), axis=0) I_even = zeros_even #Replace the row in the array with our new, shifted, row Zeros_even = np.zeros(N) #Create a zeros array (will become the new row) I_even = 2 * i #Set up the new (shifted) index for the 1 in the row I_even, I_odd = I, I #Split the identity matrix into the top and bottom half, since they have different shifting formulas N_half = int(N/2) #This is done in order to not repeatedly do int(N/2) on each array slice I implement the above pseudocode by using numpy array manipulation (this code is copy-and-pasteable): import numpy as np You can see how that works to generate M above. ![]() Shift the 1 in row i by 2*(i - N/2)+1 to the right (Full code below.) This is the mathematically correct way to generate this: I = NxN identity matrix You can check that multiplying this with M * array() = array(). So (even1, odd1, even2, odd2, even3, odd3) goes to (even1, even2, even3, odd1, odd2, odd3).įor example, with N=6, the permutation matrix would be: M = array(, ) into a 1D array where the first half are the evens, and the second half are the odds. I want to be able to generate the permutation matrix that splits a 1D array of consecutive numbers (i.e.
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |