How to count the elements of a sparse matrix in a certain region? - matlab

I have a sparse matrix and want to divide the region into 4 parts, dividing x and y in 2 equidistant pieces and want to calculate the sum of the corresponding values.
For the example below, the coordinates x-y each corresponds to [0,16] so the region is a square. There is a sparse matrix in this square, which is symmetrical. I would like to divide the region into smaller squares and sum up the sparse values. Region 0:8,0:8 has 2 elements and their values are both (2,3)=(3,2)=8 so the sum is 16.
Summation of the 1st region should give 16, 2nd and 3rd are 36 and the 4th one is 26.
x = sparse(16,16);
x (3,2) = 8;
x (10,2) = 8;
x (13,2) = 8;
x (14,2) = 4;
x (15,2) = 4;
x (2,3) = 8;
x (10,3) = 4;
x (13,3) = 4;
x (14,3) = 2;
x (15,3) = 2;
x (2,10) = 8;
x (3,10) = 4;
x (13,10) = 4;
x (14,10) = 2;
x (15,10) = 2;
x (2,13) = 8;
x (3,13) = 4;
x (10,13) = 4;
x (14,13) = 2;
x (15,13) = 2;
x (2,14) = 4;
x (3,14) = 2;
x (10,14) = 2;
x (13,14) = 2;
x (15,14) = 1;
x (2,15) = 4;
x (3,15) = 2;
x (10,15) = 2;
x (13,15) = 2;
x (14,15) = 1;
i would rather appriciate a shorter way, rather than writing a line for each sub-square. lets say for 6000 sub-squares one should write 6000 lines?

Let's define the input in a more convenient way:
X = sparse([...
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 8, 0, 0, 0, 0, 0, 0, 8, 0, 0, 8, 4, 4
0, 8, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 4, 2, 2
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 8, 4, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 2
0, 4, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 0, 1
0, 4, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 1, 0]);
For convenience, we first make the array dimensions even. We don't use padarray() for this because this makes the sparse matrix full!
sz = size(X);
newX = sparse(sz(1)+1,sz(2)+1);
padTopLeft = true; % < chosen arbitrarily
if padTopLeft
newX(2:end,2:end) = X;
else % bottom right
newX(1:sz(1),1:sz(2)) = X;
end
%% Preallocate results:
sums = zeros(2,2,2);
Method #1: accumarray
We create a mask of the form:
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2
3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4
3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4
3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4
3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4
3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4
3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4
3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4
3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4
and then use it to sum the appropriate elements of newX:
sums(:,:,1) = reshape(...
accumarray(reshape(repelem([1,2;3,4], ceil(sz(1)/2), ceil(sz(2)/2)),[],1),...
reshape(newX, [],1),...
[],#sum) ,2,2);
Method #2: blockproc (requires the Image Processing Toolbox)
sums(:,:,2) = blockproc(full(newX), ceil(sz/2), #(x)sum(x.data(:)));
Several notes:
I also tried histcounts2, which is very short, but it only tells you the amount of values in each quadrant, not their sum:
[r,c] = find(newX);
histcounts2(r,c,[2,2])
I might've overcomplicated the accumarray solution.

Although your question is not very precise and you don't made any efford to find a solution, here is what you are asking..
clear;clc;close;
Matrix=rand(20,20);
Acc=zeros(1,4);
Acc(1)=sum(sum( Matrix(1:size(Matrix,1)/2,1:size(Matrix,2)/2) ));
Acc(2)=sum(sum( Matrix((size(Matrix,1)/2)+1:end,1:size(Matrix,2)/2)));
Acc(3)=sum(sum( Matrix(1:size(Matrix,1)/2,((size(Matrix,2)/2)+1):end )));
Acc(4)=sum(sum( Matrix((size(Matrix,1)/2)+1:end,((size(Matrix,2)/2)+1):end)));
% Verification
sum(sum(Matrix)) % <- is the same with
sum(Acc) % <- this

You can define any rectangle within the matrix by defining the 4 corners of it. Then use a for loop to process all rectangles.
regions = [
1 8 1 8
9 16 1 8
1 8 9 16
9 16 9 16
];
regionsum = zeros(size(regions,1),1);
for rr = 1:size(regions,1)
submat = x(regions(rr,1):regions(rr,2),regions(rr,3):regions(rr,4));
regionsum(rr) = sum(submat(:));
end
>> regionsum
regionsum =
16
36
36
26
If you mean you want to divide the square matrix into 2^N (N>2) squares of the same size then you can write regions with a for loop.
N = 1; % 2^N-by-2^N sub-squares
L = size(x,1);
dL = L/(2^N);
assert(dL==int32(dL),'Too many divisions')
segments = zeros(2^N,2);
for nn = 1:2^N
segments(nn,:) = [1,dL]+dL*(nn-1);
end
regions = zeros(2^(2*N),4);
for ss = 1:2^N
for tt = 1:2^N
regions((2^N)*(ss-1) + tt,:) = [segments(ss,:),segments(tt,:)];
end
end
example output with dividing into 16 (N=2) square submatrices:
>> regions
regions =
1 4 1 4
1 4 5 8
1 4 9 12
1 4 13 16
5 8 1 4
5 8 5 8
5 8 9 12
5 8 13 16
9 12 1 4
9 12 5 8
9 12 9 12
9 12 13 16
13 16 1 4
13 16 5 8
13 16 9 12
13 16 13 16
>> regionsum
regionsum =
16
0
12
24
0
0
0
0
12
0
0
8
24
0
8
10
>>

Related

How to render a structured mesh in Octave

I would like to recreate this sort of "cubic" surface rendering in GNU Octave:
[From AEG Mesher documentation]
How can I achieve this, given a list of coordinates which represent a surface or volume in a structured grid?
Obviously there's probably much more elaborate frameworks out there, but just to demonstrate the concept: the idea that you can only work with triangular patches is incorrect. You can specify your own patches as elaborately as you want.
In the following example, I create a simple function which draws a 3D cube 'patch', to be treated as a 'pixel' element in a structured 'mesh'.
function drawpatchpixel( x, y, z, c )
Vertices = [ 0, 0, 0
0, 1, 0
1, 1, 0
1, 0, 0
0, 0, 1
0, 1, 1
1, 1, 1
1, 0, 1 ];
Faces = [ 1, 2, 3, 4 # front
2, 6, 7, 3 # top
5, 6, 7, 8 # back
1, 5, 8, 4 # bottom
1, 2, 6, 5 # left
4, 3, 7, 8 ]; # right
patch( 'Faces', Faces, 'Vertices', Vertices + [x, y, z], 'facecolor', c )
endfunction
Then I simply draw the pixels in the preferred colour:
Pixels = { 0, 0, 0, 'r'; # base
1, 0, 0, 'r';
2, 0, 0, 'r';
3, 0, 0, 'r';
4, 0, 0, 'r';
4, 1, 0, 'r';
4, 2, 0, 'r';
4, 3, 0, 'r';
4, 4, 0, 'r';
3, 4, 0, 'r';
2, 4, 0, 'r';
1, 4, 0, 'r';
0, 4, 0, 'r';
0, 3, 0, 'r';
0, 2, 0, 'r';
0, 1, 0, 'r';
0, 0, 1, [0.5, 0.5, 0.5]; # pillars
0, 0, 2, [0.5, 0.5, 0.5];
0, 0, 3, [0.5, 0.5, 0.5];
0, 0, 4, [0.5, 0.5, 0.5];
4, 0, 1, [0.5, 0.5, 0.5];
4, 0, 2, [0.5, 0.5, 0.5];
4, 0, 3, [0.5, 0.5, 0.5];
4, 0, 4, [0.5, 0.5, 0.5];
4, 4, 1, [0.5, 0.5, 0.5];
4, 4, 2, [0.5, 0.5, 0.5];
4, 4, 3, [0.5, 0.5, 0.5];
4, 4, 4, [0.5, 0.5, 0.5];
0, 4, 1, [0.5, 0.5, 0.5];
0, 4, 2, [0.5, 0.5, 0.5];
0, 4, 3, [0.5, 0.5, 0.5];
0, 4, 4, [0.5, 0.5, 0.5];
0, 1, 4, 'g'; # roof
0, 2, 4, 'g';
0, 3, 4, 'g';
4, 1, 4, 'g';
4, 2, 4, 'g';
4, 3, 4, 'g';
1, 0, 4, 'g';
2, 0, 4, 'g';
3, 0, 4, 'g';
1, 4, 4, 'g';
2, 4, 4, 'g';
3, 4, 4, 'g';
};
NPixels = size( Pixels, 1 );
for i = 1 : NPixels
drawpatchpixel( Pixels{i, :} )
endfor
axis equal
view( 30, 30 )
xlabel( 'x'); ylabel('y'), zlabel('z');
camlight
Result:

multiply the number in the array if it matches the given one

I have an array like this, and I need to multiply a number if it is 3, but in the end reduce eliminates all numbers equal to 3, and multiplies the rest. How do I fix this ?
let arr = [2, 4, 3, 1, 4, 3, 1, 3, 10, 4, 2, 13]
let aaa = arr.reduce([]) { $1 == 3 ? $0 : $0 + [$1 * 5] }
//[10, 20, 5, 20, 5, 50, 20, 10, 65]
//[2,4,15,1,4,15,1,15,10,4,2,13] need this
You should use map instead of reduce
let arr = [2, 4, 3, 1, 4, 3, 1, 3, 10, 4, 2, 13]
let result = arr.map { $0 == 3 ? 15 : $0 }
// [2, 4, 15, 1, 4, 15, 1, 15, 10, 4, 2, 13
Or if it should work for any multiple of 3
let result = arr.map { $0.isMultiple(of: 3) ? $0 * 5 : $0 }

How to manage the hidden state dims when using pad_sequence?

Using Pytorch LSTM architecture trying to build a text generation model. For every batch, I'm using pad_sequence to have min padding for every sequence, therefore I have a variable dims batch (batch_size * seq_len). I'm applying also pack_padded_seq to only give the non-zero (non-padding) tokens to the LSTM. But, the variable dims batch throws an error while feeding it to the LSTM as following; Expected hidden[0] size (1, 8, 16), got (1, 16, 16). In this error, I have provided batch size 16 with 8 tokens for every sequence, but the hidden state is 16 * 16.
I have tried to create the hidden state in the forward function, but that did not work well. How can I create the hidden state such that it can accept variable dims batch and it will not be lost for the whole epoche?
class RNNModule(nn.Module):
def __init__(self, n_vocab, seq_size, embedding_size, lstm_size):
super(RNNModule, self).__init__()
self.seq_size = seq_size
self.lstm_size = lstm_size
self.embedding, num_embeddings, embedding_dim = create_emb_layer(weight_matrix, False)
self.lstm = nn.LSTM(embedding_size,
lstm_size,
num_layers=flags.n_layers,
batch_first=True
)
self.dense = nn.Linear(lstm_size, n_vocab)
def forward(self, x,length,prev_state):
embed = self.embedding(x)
packed_input = db.pack_src(embed,length)
packed_output, state = self.lstm(packed_input,prev_state)
padded,_ = db.pad_pack(packed_output)
logits = self.dense(padded)
return logits, state
def zero_state(self, batch_size = flags.batch_size):
return (torch.zeros(flags.n_layers, batch_size, self.lstm_size),
torch.zeros(flags.n_layers, batch_size, self.lstm_size))
input: tensor([[ 19, 9, 4, 3, 68, 8, 6, 2],
[ 19, 9, 4, 3, 7, 8, 6, 2],
[ 3, 12, 17, 10, 6, 40, 2, 0],
[ 4, 3, 109, 7, 6, 2, 0, 0],
[ 188, 6, 7, 18, 3, 2, 0, 0],
[ 4, 3, 12, 6, 7, 2, 0, 0],
[ 6, 7, 3, 13, 2, 0, 0, 0],
[ 3, 28, 17, 69, 2, 0, 0, 0],
[ 6, 3, 12, 11, 2, 0, 0, 0],
[ 3, 13, 6, 7, 2, 0, 0, 0],
[ 3, 6, 7, 13, 2, 0, 0, 0],
[ 6, 3, 23, 7, 2, 0, 0, 0],
[ 3, 28, 10, 2, 0, 0, 0, 0],
[ 6, 3, 23, 2, 0, 0, 0, 0],
[ 3, 6, 37, 2, 0, 0, 0, 0],
[1218, 2, 0, 0, 0, 0, 0, 0]])
Zero tokens are padding.
Embedding size: 64
LSTM size: 16
batch size: 16
The size of the hidden state you create has the correct size, but your input does not. When you pack it with nn.utils.rnn.pack_padded_sequence you've set batch_first=False, but your data has size [batch_size, seq_len, embedding_size] when you pass it to the packing, so that has batch_size as the first dimension. Also for the LSTM you use batch_first=True, which is appropriate for your data.
You only need to pack it correctly by setting batch_first=True as well, to match the order of your data.
rnn_utils.pack_padded_sequence(embed,length,batch_first=True)

Remove zero rows from a list of list in Scala

I have a list of list in Scala such as:
val lst = List(List(60, 0, 1, 2, 3, 28, 0, 0, 0, 0), List(0, 0, 0, 0, 0, 0, 0, 0, 0, 0), List(47, 0, 1, 1, 2, 28, 0, 0, 0, 0))
and I want to remove all zero rows and the result should be like:
List(List(60, 0, 1, 2, 3, 28, 0, 0, 0, 0), List(47, 0, 1, 1, 2, 28, 0, 0, 0, 0))
Does Scala list have any built-in method to remove these rows?
You can use filter to keep only items (lists) matching a predicate; The predicate can use exists to check for non-zero elements:
lst.filter(_.exists(_ != 0))
#Tzach Zohar answer is perfectly fine but here is another way to approach it.
scala> lst.filterNot(xs => xs.forall(_ == 0))
res0: List[List[Int]] = List(
List(60, 0, 1, 2, 3, 28, 0, 0, 0, 0),
List(47, 0, 1, 1, 2, 28, 0, 0, 0, 0)
)

Extendible hashing for file with given search key values for records

I know that SO might be the wrong place to look for answers to questions such as these, but at the moment I need the answer and how to work it out step by step urgently.
Suppose that we are using extendable hashing on a file that contains records
with the following search-key values:
2, 3, 5, 7, 11, 17, 19, 23, 29, 31
Show the extendable hash structure for this file if the hash function is h(x) = x
mod 8 and buckets can hold three records.
EDIT: I have the "supposed" answer to this: http://i.imgur.com/CW8H8vG.png
But I am not sure if this is correct, since when I work it out, I get a different hash structure. If it is correct, could anyone explain to me why?
h(2) = 2 => 0, 0, 2, 0, 0, 0, 0, 0
h(3) = 3 => 0, 0, 2, 3, 0, 0, 0, 0
h(5) = 5 => 0, 0, 2, 3, 0, 5, 0, 0
h(7) = 7 => 0, 0, 2, 3, 0, 5, 0, 7
h(11) = 3 => 0, 0, 2, { 3, 11 }, 0, 5, 0, 7
h(17) = 1 => 0, 17, 2, { 3, 11 }, 0, 5, 0, 7
h(19) = 3 => 0, 17, 2, { 3, 11, 19 }, 0, 5, 0, 7
h(23) = 7 => 0, 17, 2, { 3, 11, 19 }, 0, 5, 0, { 7, 23 }
h(29) = 5 => 0, 17, 2, { 3, 11, 19 }, 0, { 5, 29 }, 0, { 7, 23 }
h(31) = 7 => 0, 17, 2, { 3, 11, 19 }, 0, { 5, 29 }, 0, { 7, 23, 31 }