Related
Suppose I have a matrix such as P = [[0,1],[1,0]] and a vector v = [a,b]. If I multiply them I have:
Pv = [b,a]
The matrix P is simply a permutation matrix, which changes the order of each element.
Now suppose that I have the same P, but I have the matrices M1 = [[1,2],[3,4]] and M2=[[5,6],[7,8]]. Now let me combine them as the 3D Tensor T= [[[1,2],[3,4]], [[5,6],[7,8]]] with dimensions (2,2,2) - (C,W,H). Suppose I multiply P by T such that:
PT = [[[5,6],[7,8]], [[1,2],[3,4]]]
Note that now M1 now equals [[5,6],[7,8]] and M2 equals [[1,2],[3,4]] as the values have been permuted across the C dimension in T (C,W,H).
How can I multiply PT (P=2D tensor,T=3D tensor) in pytorch using matmul? The following does not work:
torch.matmul(P, T)
An alternative solution to #mlucy's answer, is to use torch.einsum. This has the benefit of defining the operation yourself, without worrying about torch.matmul's requirements:
>>> torch.einsum('ij,jkl->ikl', P, T)
tensor([[[5, 6],
[7, 8]],
[[1, 2],
[3, 4]]])
Or with torch.matmul:
>>> (P # T.flatten(1)).reshape_as(T)
tensor([[[5, 6],
[7, 8]],
[[1, 2],
[3, 4]]])
You could do something like:
torch.matmul(P, X.flatten(1)).reshape(X.shape)
I have a hard time understanding the difference between these two kinds of indexing.
Let's say I have a nested nested list:
x = np.array([[[1,2],[5,6]],[[9,7],[12,23]]])
if I did
x[:][:][1] and x[:,:,1]
I would get
[[9 7][12 23]]
[[5 6][12 23]]
respectively.
To be honest, I have no clue as to how I would get these results. Could someone explain the steps to me as to how I would get these arrays ?
This has to do with python's slice syntax. Essentially, obj[a:b:c] is syntactic shorthand for obj.__getitem__(slice(a,b,c)).
x[:] simply returns a 'full slice' of x - that is, it returns an exact copy of x. Doing x[:][:][1] is no different from doing x[1].
Meanwhile, doing x[:,:,1] equates to:
x.__getitem__((slice(), slice(), 1))
that is, using a 3-tuple as an index. For an ordinary python list, this would fail, but Numpy accepts it gracefully. To see how Numpy does so, let's look a bit closer at this example:
>>> x = np.array([[[1,2],[5,6]],[[9,7],[12,23]]])
>>> x[1]
array([[ 9, 7],
[12, 23]])
>>> x[:,1]
array([[ 5, 6],
[12, 23]])
>>> x[:,:,1]
array([[ 2, 6],
[ 7, 23]])
>>> x[:,:,:,1]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: too many indices for array: array is 3-dimensional, but 4 were indexed
We can see a pattern.
When you give a Numpy array a tuple as an index, it maps each element of the tuple to a dimension, and then applies the subsequent elements of the tuple to each of those dimensions. In short:
x[1] just gets the element at index 1 from the first dimension of the array. This is the single element [[9, 7], [12, 23]]
x[:, 1] gets the element at index 1 from each element in the first dimension of the array. Which is to say, it gets the elements at index 1 from the second dimension of the array. This is two elements: [5, 6] and [12, 23]. Numpy groups them together in a list.
x[:, :, 1] follows the same pattern - it gets the elements at index 1 from the third dimension of the array. This time there are four unique elements: 2 and 6 from the first element in the second dimension, and, 7 and 23 from the second element in the second dimension. Numpy groups them by dimension in a nested list.
x[:, :, :, 1] fails, because the array only has three dimensions - there's no way to further subdivide any of the third dimension's elements.
I have a 2-dimensional array with each element being a list of valid values
(pseudosyntax):
[ [1,2] [1,2]
[1,2] [1,2] ]
so effectively it's a 3-dim array/list/matrix (whatever Python calls those.)
It is generated by
import numpy as np
grid = np.full((borderSize, borderSize, borderSize), range(1, borderSize + 1))
What is the best practice to remove a value from an array on the "deepest" level?
Pseudocode:
grid = [ [1,2] [1,2]
[1,2] [1,2] ]
grid[0,1].remove(not index but value 2)
#result: grid = [ [1,2] [1]
[1,2] [1,2] ]
I did attempt every solution I could google, including numpy.delete() and array.remove(), any whatever that syntax is: arr = arr[ (arr >= 6) & (arr <= 10) ]. All the approaches seem to "flatten" the array/list/matrix, or throw cryptic-to-me errors ("can't broadcast array into shape")
Thanks!
Arrays don't really have such a thing as a "deepest" level, they have dimensions and each and every dimension has to be defined globally. You can change your array to a list and then remove the element like that:
grid = np.array([ [1,2], [1,2],
[1,2], [1,2] ])
grid = grid.tolist()
del grid[1][1]
grid
result:
[[1, 2], [1], [1, 2], [1, 2]]
but you cannot do this on an array.
I want to return the diagonals i.e. from left to right and from right to left in a given matrix, Im using list comprehensionsto do so but I came up, in my eyes with a to complicated comprehension that returns the left to right matrix.
I was wondering if there are simpler ways to write a comprehension that returns the right to left diagonal ? Also, given that im a noob, im only beginning to dive into learning the language, i was wondering if the right_left comprehension is even conventional ?
matrix = [[1,2,3],
[4,5,6],
[7,8,9]]
left_right = [arr[i][i]
for i in range(len(arr))]
right_left = [arr[i][[-j
for j in range(-len(arr)+1,1)][i]]
for i in range(-len(arr),0)]
left_right = [arr[i][-(i+1)] for i in range(len(arr))]
For explanation of negiative indicies read this: https://stackoverflow.com/a/11367936/8326775
[list(reversed(matrix[i]))[i] for i in range(len(matrix))]
# more transparent version:
for i in range(len(matrix)):
row = list(reversed(matrix[i]))
el = row[i]
print("reversed row {} = {} -> extract element {} -> gives {}".format(i, row, i, el))
#reversed row 0 = [3, 2, 1] -> extract element 0 -> gives 3
#reversed row 1 = [6, 5, 4] -> extract element 1 -> gives 5
#reversed row 2 = [9, 8, 7] -> extract element 2 -> gives 7
You're probably better off learning about numpy, which has a function for diagonals built-in
>>> import numpy as np
>>> matrix = np.array([[1,2,3],
[4,5,6],
[7,8,9]])
>>> np.diag(matrix)
array([1, 5, 9])
>>> np.diag(matrix, k=1)
array([2, 6])
>>> np.diag(matrix, k=-1)
array([4, 8])
I am reading Hutton's book, Programming in Haskell.
Here is a function:
pairs :: [a] -> [(a,a)]
pairs xs = zip xs (tail xs)
e.g.
>pairs [1,2,3,4]
>[(1,2),(2,3),(3,4)] --result
Problem is how to read this function ? from left to right?
I am confused how "tail" leave 1 element and then combine it with next element using "zip"
Since "tail" suppose to get all remaining elements from the list right?
I haven't read the book you mentioned, but I'll try to explain what I know.
You're right about the tail function returning everything except the first element of the list. Let's see how zip works,
zip [1, 2, 3, 4] [5, 6, 7, 8]
gives,
[(1, 5), (2, 6), (3, 7), (4, 8)]
Now, consider the output we need from the input we have, observe the transformation required from input to output,
[1, 2, 3, 4] -> [(1,2),(2,3),(3,4)]
From the above application of zip, we can see the output we need can be obtained by calling zip with,
zip [1, 2, 3] [2, 3, 4]
Now, from the docs on zip function, we can see that if the two given lists are of unequal length, the extra items in the longer list are discarded. So, we'd get the same result with,
zip [1, 2, 3, 4] [2, 3, 4]
in which the last 4 in the first input list would be discarded and we get the result we want.
This can be written in a function as,
pairs xs = zip xs (tail xs)
If it is something else you are confused about, do let me know.
zip takes 2 arguments. tail returns its argument with the first element removed, but does not modify its argument.Therefore [1, 2, 3, 4] gets zipped with [2, 3, 4].