Suppose I have a 5 dimensional matrix v and now I want a new matrix D fulfilling
D[a, b, n, m, d] = v[a, b, n, n, d]-v[a, b, m, m, d].
How do I elegantly do this in numpy?
How do you want to change the dimensionality? You can reshape it like this
import numpy as np
a, b, n, d = 2, 3, 4, 5
v = np.zeros((a, b, n, n, d))
D = v.reshape((a, b, n*n, d))
I found einsum can do this:
D = np.einsum('abiic->abic', v)[..., None, :] - np.einsum('abiic->abic', v)[:, :, None, ...]
Related
i have a question regarding the efficient operation of the pytorch tensor multidimensional selection.
Assuming i have a tensor a, with
# B=2, V=20000, d=64
a = torch.rand(B, V, d)
and a tensor b, with
# B=2, N=30000, k=10; k is the index inside of [0, V]
b = torch.randint(0, V, (B, N, k))
The target is to construct a selected tensor from a, namely
help_1 = a[:, None, :, :].repeat(1, N, 1, 1) # [B, N, V, d]
help_2 = b[:, :, :, None].expand(-1,-1,-1,d) # [B, N, k, d]
c = torch.gather(help_1, dim=2, index=help_2)
this operation can indeed output the desired results, but is not very efficient since i created a very large help_1 matrix, which has size [2, 30000, 20000, 64]. I wonder if anyone has idea about doing this without creating such a large helper tensor for selection? Thank you!
You could use broadcasting with the indexing to save memory. Something like the following would work.
idx0 = torch.arange(B, device=b.device).reshape(-1, 1, 1, 1) # [B, 1, 1, 1]
idx1 = b[..., None] # [B, N, k, 1]
idx2 = torch.arange(d, device=b.device).reshape(1, 1, 1, -1) # [1, 1, 1, d]
c = a[idx0, idx1, idx2] # [B, N, k, d]
I have two tensors, x and y, of shape [B, D]. I want to do something like the following code
B, D = x.shape
x = tf.expand_dims(x, 1) # [B, 1, D]
y = tf.expand_dims(y, -1) # [B, D, 1]
z = x * y # [B, D, D]
z = tf.reshape(z, (B, D**2))
Is there a function in Tensorflow that already does this?
I have a 8-10 sample arrays.
[W, T, I, Z, F]
[a, F, k, D, P]
[A, B, C, D, E]
[W, F, T, P, I]
[W, T, I, Z, F]
[H, c, B, V, C]
...
...
Each array has a unique value.
[0.4729,
0.7075,
0.8611,
0.8512,
0.4769,
0.3074
...
...]
I want to select best population.This population should include 5 different values. Any idea?
Note:If results are near to 1 , this means this population is better.
Thanks,
I have two pytorch tensors:
X with shape (A, B, C, D)
I with shape (A, B)
Values in I are integers in range [0, C).
What is the most efficient way to get tensor Y with shape (A, B, D), such that:
Y[i][j][k] = X[i][j][ I[i][j] ][k]
You probably want to use torch.gather for the indexing and expand to adjust I to the required size:
eI = I[..., None, None].expand(-1, -1, 1, X.size(3)) # make eI the same for the last dimension
Y = torch.gather(X, dim=2, index=eI).squeeze()
testing the code:
A = 3
B = 4
C = 5
D = 7
X = torch.rand(A, B, C, D)
I = torch.randint(0, C, (A, B), dtype=torch.long)
eI = I[..., None, None].expand(-1, -1, 1, X.size(3))
Y = torch.gather(X, dim=2, index=eI).squeeze()
# manually gather
refY = torch.empty(A, B, D)
for i in range(A):
for j in range(B):
refY[i, j, :] = X[i, j, I[i,j], :]
(refY == Y).all()
# Out[]: tensor(1, dtype=torch.uint8)
If I have an equation, (a + (b - c) d - e) f = 75, how can I iterate through changing my variables a thru f? If a thru f are unique numbers [1,6], then there would be 6! ways of placing the numbers, right? So I imagine I have to increment through my variables somehow.
Assumptions/Limitations:
a-f are unique integers [1,6]
I'm using python and trying to solve without using built-in functions or libraries
Use 6 nested for-loops to enumerate all ways of setting each of a, b, c, d, e, and f to the values 1-6 (part I'm having an issue understanding how to organize)
Apparently there is only one permutation that will solve this particular equation
This seems like a good occasion to use sets:
In [17]: set1 = set([1,2,3,4,5,6])
In [18]: for a in set1:
...: for b in set1 - set([a]):
...: for c in set1 - set([a,b]):
...: for d in set1 - set([a,b,c]):
...: for e in set1 - set([a,b,c,d]):
...: for f in set1 - set([a,b,c,d,e]):
...: if (a + (b - c)*d - e)*f == 75:
...: print('found:', a, b, c, d, e, f)
...: break
...:
found: 4 6 2 3 1 5
In [19]: (4+(6-2)*3-1)*5
Out[19]: 75
By using the difference between sets, you make sure that you don't use the same value twice. For example:
In [20]: set([1,2,3,4,5,6]) - set([1,5])
Out[20]: {2, 3, 4, 6}
You can use itertools.permutations (the documentation contains a code sample if you don't want to use it directly):
>>> def func(a, b, c, d, e, f):
... return (a + (b - c) * d - e) * f == 75
>>> from itertools import permutations
>>> next(filter(lambda x: func(*x), permutations(range(1, 7), 6)))
(4, 6, 2, 3, 1, 5)