What is setNumInputDims in Torch supposed to be doing? - torch

minibatch = torch.Tensor(5, 2, 3,5)
m = nn.View(-1):setNumInputDims(1)
m:forward(minibatch)
gives a tensor of size
30x5
m = nn.View(-1):setNumInputDims(3)
m:forward(minibatch)
gives a tensor of size
5 x 30
m = nn.View(-1):setNumInputDims(2)
m:forward(minibatch)
gives a tensor of size
10 x 15
What is going on? I don't understand why I'm getting the dimensions I am.
The reason I don' think I understand it is that I'm thinking that the View m is expecting n dims as the input. So if n = 1, then we take 5 as the 1st dim and 30 as the 2nd dim, which is what seems to be happening when the numInputDims is set to 2.

As its name indicates, View(-1):setNumInputDims(n) is to set the number of input dimensions of View(-1).
To understand the role of View(-1), please refer to How view() method works for tensor in torch
If there is any situation that you don't know how many rows you want but are sure of the number of columns then you can mention it as -1(You can extend this to tensors with more dimensions. Only one of the axis value can be -1). This is a way of telling the library; give me a tensor that has these many columns and you compute the appropriate number of rows that is necessary to make this happen.
So View(-1) converts the input to a two-dimensional matrix. Note View(-1) corresponds to the columns of this matrix. Hence its input dimension is the latter half of the complete input. Its number of dimensions means how many dimensions are "allocated" for the columns, and any dimensions before these dimensions are used for the rows.
Therefore in your example:
minibatch = torch.Tensor(5, 2, 3,5)
m = nn.View(-1):setNumInputDims(2)
It allocates the last two dimensions (3*5) to the columns and the first two dimensions (5*2) to the rows. The result tensor is then 10*15.

Related

Generate sets from given overlap matrix

Note: I edited the original question to explain more precisely.
While I was doing a simulation for my new method, I needed to generate a special type of dataset consists of multiple subset. The problem is that there is some "shared" variables across the subsets, and the number of shared variable is called "overlap" here. Since the distribution of overlap proportion is given, I need to generate an appropriate list of variables and their overlap follows the given distribution. But I have failed to implement such algorithm...
I am not sure whether there is a specific algorithm for this kind of question,
but I have failed to find such thing after a long search.
I prefer R solution, but anything others also will be very appreciated. Please help me to solve this problem! Thank you so much in advance!
The below is a standardized explanation for my problem. I tried to explain as general as possible I can, but please give me any suggestion if it is not sufficient.
Purpose: Generate n sets from given overlap matrix of elements. Each set contains k elements.
Input: There is a n*n matrix whose (i,j)th cell value represents a number of overlapped elements from (i)th set to (j)th set.
Output: A list of k element identifiers (whatever can be used such as number) for n sets.
Assumption: The number of elements for each set is k, and it is same across all n sets. Hence, the input matrix is symmetric.
Example (assumes k=3 and n=3)
Input
3 1 0
1 3 1
0 1 3
Output
Set 1: A B C
Set 2: A D E
Set 3: D F G
In the above example input, (1,2)th and (2,1)th cells are 1 because set 1 and 2 share "A" element and vice versa, and diagonal cells are 3(=k) because each set shares all elements with itself.
I would repeat the following process until I had accounted for all the matrix entries:
1) Treat the matrix as the adjacency matrix of a graph, and find the largest clique in it. That is, find the largest possible set S of indexes such that for all i, j in set S M(i,j) > 0
2) Create an item that is in all of the sets which correspond to the indexes in S - in fact, if the minimum value of M(i,j) = v, create v such items.
3) subtract v from M(i,j) for all i, j in set S, accounting for the counts generated by the items you have just created.

Piecewise / Noncontiguous Ranges?

Is there any kind of object class for piecewise / noncontiguous ranges in Julia? For instance, I can create a regular range:
a = UnitRange(1:5)
But, if I wanted to combine this with other ranges:
b = UnitRange([1:5, 8:10, 4:7])
I cannot currently find an object or method. There is a PiecewiseIncreasingRanges module (https://github.com/simonster/PiecewiseIncreasingRanges.jl) that would be just what I want in this situation, except that it, as the name implies, requires the ranges be monotonically increasing.
The context for this is that I am looking for a way to create a compressed, memory efficient version of the SparseMatrixCSC type for sparse matrices with repeating rows. The RLEVectors module will work well to save space on the nonzerovalue vector in the sparse matrix class. Now though I am trying to find something to save space for the rowvalue vector that also defines the sparse matrix, since series of repeating rows will result in ranges of values in that vector (e.g. if the first 10 rows, or even certain columns in the first ten rows, of a sparse matrix are identical, then there will be a lot of 1:10 patterns in the row value vector).
More generally, I'd like a range such as the b object that I try to create above over which I could do an iterated loop, getting:
for (idx, item) in enumerate(hypothetical_object)
println("idx: $idx, item: $item")
end
idx: 1, item: 1
idx: 2, item: 2
...
idx: 5, item: 5
idx: 6, item: 8
idx: 7, item: 9
idx: 8, item: 10
idx: 9, item: 4
idx: 10, item: 5
...
Update: One thing I'm considering, and will probably try implementing if I don't hear other suggestions here, will be to just create an array of PiecewiseIncreasingRange objects, one for each column in my sparse matrix. (I would probably also then break the nonzero value vector into an array of separate pieces, one for each column of my sparse matrix as well). This would at least be relatively simple to implement. I don't have a good sense off the bat how this would compare in terms of computational efficiency to the kind of object I am searching for in this question. I suspect that memory requirements would be about the same.
To loop over a sequence of ranges (or other iterators), you can use the chain function in the Iterators.jl package.
For example:
using Iterators
b = chain(1:5, 8:10, 4:7)
for i in b
println(i)
end
outputs the elements of each range.

for loop for scalar product with a matrix

I'm trying to fill a 10 x 1500 matrix with a loop.
I have to fill that matrix with 150 small 10 x 10 matrixes. I have tried to implement this with a double loop, but unsuccessfully. My problem is that each 10*10 matrix is the result of a scalar product.
At the begin it seems to be easy, but then I realized I couldn't figure out the sizes of the 10 x 1500 matrix with the 150 small 10*10 matrixes.
Here is what I did:
es_var is a 1 x 150 matrix, which I converted to a vector to simplify the scalar product (at least in my opinion).
diax is a 10 x 10 matrix.
I want to multiply each value of the es_var vector per the whole diag 10*10 matrix.
I am having troubles because I don't manage to input R in filling 10 rows per time. Thus in the end I get a 10*1500 matrix, but it is the same 10*10 time matrix repeated 150 times.
Here is my code
es_var1 = as.vector(es_var)
v = matrix(0, 10, 10*N)
for (i in 1:N){
v[,] = es_var1[i] * diax
}
Can somebody help in figuring out this, please? I spent the whole day trying it. And I need to do that without using in build functions since this is a small part of a big math demonstration I have to implement.
If I understand your requirement correctly, you can accomplish this with the following line:
v <- matrix(diax,10,1500)*rep(es_var1,each=100);
This constructs a 10x1500 matrix with the 10x10 diax matrix as the initial values, cycled sufficiently to cover the complete 10x1500 size. Then, to apply the es_var1 multiplication, you can replicate each of its elements 100 times, such that they will naturally align with each consecutive 10x10 small matrix during vectorized multiplication.

Make vector with 2 elements with equal chance in R

I want to create an R vector with two repeat elements. A length of the array is 200.
But each element can be either 'x' or 'y'.
an element can be x or y with equal chance.
Is there any grammatical function in R to do above task?
Please someone help.
A possible way to do it is to use rbinom. Step by step, generate first a vecotr of 0 and 1, then change it into x and y:
vec = ifelse(rbinom(200, 1, 0.5)==0,"x","y"))
We need a little bit more information to be helpful, but if you want a vector of 200 values, 100 x's and 100 y's, then just do this:
t <- rep(c('X','Y'), 100)
If you want this in a random order:
t <- sample(t)

In R: sort the maximum dissimilarity between rows in a matrix

I have a matrix, which includes 100 rows and 10 columns, here I want to compare the diversity between rows and sort them. And then, I want to select the 10 maximum dissimilarity rows from it, Which method can I use?
set.seed(123)
mat <- matrix(runif(100 * 10), nrow = 100, ncol = 10)
My initial method is to calculate the similarity (e.g. saying tanimoto coefficient or others: http://en.wikipedia.org/wiki/Jaccard_index ) between two rows, and dissimilairty = 1 - similarity, and then compare the dissimilarty values. At last I will sort all dissimilarity value, and select the 10 maximum dissimilarity values. But it seems that the result is a 100 * 100 matrix, maybe need efficient method to such calculation if there are a large number of rows. However, this is just my thought, maybe not right, so I need help.
[update]
After looking for some literatures. I find the one definition for the maximum dissimilarity method.
Maximum dissimilarity method: It begins by randomly choosing a data record as the first cluster center. The record maximally distant from the first point is selected as the next cluster center. The record maximally distant from both current points is selected after that . The process repeats itself until there is a sufficient number of cluster centers.
Here in my question, the sufficient number should be 10.
Thanks.
First of all, the Jacard Index is not right for you. From the wikipedia page
The Jaccard coefficient measures similarity between finite sample sets...
Your matrix has samples of floats, so you have a different problem (note that the Index in question is defined in terms of intersections; that should be a red flag right there :-).
So, you have to decide what you mean by dissimilarity. One natural interpretation would be to say row A is more dissimilar from the data set than row B if it has a greater Euclidean distance to the center of mass of the data set. You can think of the center of mass of the data set as the vector you get by taking the mean of each of the colums and putting them together (apply(mat, 2, mean)).
With this, you can take the distance of each row to that central vector, and then get an ordering on those distances. From that you can work back to the rows you desire from the original matrix.
All together:
center <- apply(mat, 2, mean)
# not quite the distances, actually, but their squares. That will work fine for us though, since the order
# will still be the same
dists <- apply(mat, 1, function(row) sum((row - center) ** 2))
# this gives us the row indices in order of least to greaest dissimiliarity
dist.order <- order(dists)
# Now we just grab the 10 most dissimilar of those
most.dissimilar.ids <- dist.order[91:100]
# and use them to get the corresponding rows of the matrix
most.dissimilar <- mat[most.dissimilar.ids,]
If I was actually writing this, I probably would have compressed the last three lines as most.dissimilar <- mat[order(dists)[91:100],], but hopefully having it broken up like this makes it a little easier to see what's going on.
Of course, if distance from the center of mass doesn't make sense as the best way of thinking of "dissimilarity" in your context, then you'll have to amend with something that does.

Resources