Delete rows in a vector starting from a specific index Matlab - matlab

I have an nx1 vector in Matlab. I want to delete rows starting from a specific index. For example, if n is 100 and the index is 60 then all rows from 60 till 100 will be removed. I've found this REMOVEROWS but I don't know how to make it do this.

The removerows function is probably overkill for a vector, but here is how it can be used along with the usual linear indexing method:
n = 100;
index = 60;
a = rand(n,1); % An n-by-1 column vector
b1 = a(1:index-1)
b2 = removerows(a,'ind',index:n) % Or removerows(a,'ind',index:size(a,1))
Note that the removerows function is in the Neural Network toolbox and thus not part of core Matlab.

This should the trick:
your_vector(index:end) = [];
If you want to remove from the end that you can do:
your_vector(end-index+1:end) = [];

Related

Create a submatrix using random columns and loop

I have a 102-by-102 matrix. I want to select square sub-matrices of orders from 2 up to 8 using random column numbers. Here is what I have done so far.
matt is the the original matrix of size 102-by-102.
ittr = 30
cols = 3;
for i = 1:ittr
rr = randi([2,102], cols,1);
mattsub = matt([rr(1) rr(2) rr(3)], [rr(1) rr(2) rr(3)]);
end
I have to extract matrices of different orders from 2 to 8. Using the above code I would have to change the mattsub line every time I change cols. I believe it is possible to do with another loop inside but cannot figure out how. How can I do this?
There is no need to extract elements of a vector and concatenate them, just use the vector to index a matrix.
Instead of :
mattsub = matt([rr(1) rr(2) rr(3)], [rr(1) rr(2) rr(3)]);
Use this:
mattsub = matt(rr, rr);
Defining a set of random sizes is pretty easy using the randi function. Once this is done, they can be projected along your iterations number N using arrayfun. Within the iterations, the randperm and sort functions can be used in order to build the random indexers to the original matrix M.
Here is the full code:
% Define the starting parameters...
M = rand(102);
N = 30;
% Retrieve the matrix rows and columns...
M_rows = size(M,1);
M_cols = size(M,2);
% Create a vector of random sizes between 2 and 8...
sizes = randi(7,N,1) + 1;
% Generate the random submatrices and insert them into a vector of cells...
subs = arrayfun(#(x)M(sort(randperm(M_rows,x)),sort(randperm(M_cols,x))),sizes,'UniformOutput',false);
This can work on any type of matrix, even non-squared ones.
You don't need another loop, one is enough. If you use randi to get a random integer as size of your submatrix, and then use those to get random column and row indices you can easily get a random submatrix. Do note that the ouput is a cell, as the submatrices won't all be of the same size.
N=102; % Or substitute with some size function
matt = rand(N); % Initial matrix, use your own
itr = 30; % Number of iterations
mattsub = cell(itr,1); % Cell for non-uniform output
for ii = 1:itr
X = randi(7)+1; % Get random integer between 2 and 7
colr = randi(N-X); % Random column
rowr = randi(N-X); % random row
mattsub{ii} = matt(rowr:(rowr+X-1),colr:(colr+X-1));
end

How to deal with nonzero elements from rows of sparse matrix in Matlab?

I am dealing with quite a big sparse matrix, its size is about 150,000*150,000. I need to access into its rows, extract the non-zero elements and replace these values following the rule as the code below:
tic
H = [];
for i = 1: size(A,2)
[a,b,c] = find(A(i,:)); % extract the rows
add = diff([0 c(2:end) 0]); % the replacing rule
aa = i*ones(1,size(a,2)); % return back the old position of rows
G0 = [aa' b' add']; % put it back the old position with replaced values
H = [H; G0];
end
H1 = H(:,1);
H2 = H(:,2);
H3 = H(:,3);
ADD = sparse(H1,H2,H3,nm,nm,nzmax);
toc
I found that the find function is really time consuming (0.1s/rows) in this code and with this current size of my sparse matrix, it takes me up to about 33 hours for this job. I do believe there is some ways out but I am such a newborn to coding and dealing with sparse matrix is really scary.
Would you drop me some ideas?
You can use the find function once applying it on the whole array then use accumarray to apply the function on each row:
[a b c]=find(A.');
add=accumarray(b,c,[],#(x){diff([0 ;x(2:end) ;0])});
H = [b a vertcat(add{:})];

How to compare two unsorted lists in Matlab?

I have two lists of 2-dimensional points given as M x 2 - and N x 2 - matrices, respectively, with M and N possibly being very large.
What is the fastest way to determine how many of them are equal?
I am not sure whether you want to count repetitive entries, but if not you could use intersect or some quite intuitive algorithm based on sorting (see below). I would not prefer a nested-loop version...
function test_compareVecs()
%% create some random data
N = 31415;
M1 = 100000;
M2 = 200000;
vec = rand(N,2);
v1 = [rand(M1-N,2); vec];
v2 = [rand(M2-N,2); vec];
v1 = v1(randperm(M1),:);
v2 = v2(randperm(M2),:);
%% intersect
disp('intersect:');
tic
s = size(intersect(v1,v2,'rows'),1);
toc;
s
%% alternative approach
disp('alternative approach:');
tic;
s = compareVecs(v1,v2);
toc;
s
end
function s = compareVecs(v1,v2)
%% create help vector
help_vec = [[v1,zeros(size(v1,1),1)]; ...
[v2,ones(size(v2,1),1)]];
%% sort by first column
% note: for some reason "sortrows(help_vec,1)" is slower
hash_vec = help_vec(:,1); % dummy hash
[~,sidx] = sort(hash_vec);
help_vec = help_vec(sidx,:);
%% diff + compare
help_vec = diff(help_vec);
s = sum(help_vec(:,1) == 0 & ...
help_vec(:,2) == 0 & ...
help_vec(:,3) ~= 0);
end
Result
intersect:
Elapsed time is 0.145717 seconds.
s = 31415
alternative approach:
Elapsed time is 0.048084 seconds.
s = 31415
Compute all pair-wise distances with pdist2 and then count pairs with zero distance. If the coordinates are float values, you may want to use a tolerance instead of comparing against zero:
%// Data:
M = 10;
N = 8;
listM = randi(10,M,2)-1;
listN = randi(10,N,2)-1;
tol = 1e-6;
%// Distance matrix:
d = pdist2(listM, listN);
%// Count:
count = sum(d(:)<tol);
This should work irrespective of the order of the points in each list, or their lengths. It is a hash-table/dictionary solution that should be fast but with memory demand linear with the lengths of the lists. Please, note that the syntax below may not be perfect, but a quick reference to the main data structures mentioned should make corrections trivial.
(1) populate a dictionary-like containers.Map, in a way that the key is a unique function of the points, e.g. num2str(M(i,1))'-'num2str(M(i,2)).
(2) Then, go over all elements of the second list, create the key just as in (1) and check if it exists. If it does, set map(key)=1 else set it to 0. In the end, all the keys consisting of common points will have 1s stored, and the rest will be zeros.
(3) Finalize by summing over the values of the map (something like sum(map.values())) which should give you the total number of unique intersections among the two sets, irrespective of the order these points appear in each list.
OBS: if you don't want to count just unique intersections but all repeated points, in (2), rather than making map(key)=1, add 1 to map(key). The rest is the same.

Matlab Bootstrap not complete resampling

I would like to perform bootstrap in Matlab. I have 100 original data points and I would like each iteration of bootstrap to choose only 57 points with replacement randomly. How do I accomplish it?
I cannot seem to find this functionality in Matlab function bootstrp.
Regards,
To choose n points out of a vector randomly with replacement: use randi to generate the (possibly repeated) indices:
vector = (1:100).^2; %// example data
n = 57;
ind = randi(numel(vector),1,n); %// n random integers between 1 and numel(vector)
sample = vector(ind);
To do it directly with bootstrp: let fun denote the function you would pass to bootstrp. You just need to pick the first 57 values of each 100-value sample:
vector = (1:100).^2; %// example data
n = 57;
nboot = 10;
bootstrp(nboot, #(x) fun(x(1:57)), vector)

Accessing Ranges of Data in Vectorized Way MATLAB

I have a column vector of data in variable vdata and a list of indeces idx. I want to access vdata at the indeces x before and x after each index in idx. One way I would do it in a for loop is:
x = 10;
accessed_data = [];
for (ii = 1:length(idx))
accessed_data = vdata(idx-x:idx+x);
end
Is there a way to do this in a vectorized function? I found a solution to a very similar question here: Addressing multiple ranges via indices in a vector but I don't understand the code :(.
Assuming min(idx)-x>0 and max(idx)+x<=numel(vdata) then you can simply do
iidx = bsxfun(#plus, idx(:), -x:x); % create all indices
accessed_data = vdata( iidx );
One scheme that uses direct indexing instead of a for loop:
xx = (-x:x).'; % Range of indices
idxx = bsxfun(#plus,xx(:,ones(1,numel(idx))),idx(:).'); % Build array
idxx = idxx(:); % Columnize to interleave columns
idxx = idxx(idxx>=1&idxx<=length(vdata)); % Make sure the idx+/-x is valid index
accessed_data = vdata(idxx); % Indices of data
The second line can be replaced with a form of the first line from #Shai's answer. This scheme checks that all of the resultant indices are valid. Because some might have to be removed, you could end up with a ragged array. One way to solve this is to use cell arrays, but here I just make idxx a vector, and thus accessed_data is as well.
This gives the solution in a matrix, with one row for each value in idx. It assumes that all values in idx are greater than or equal to x, and less than or equal to length(vdata)-x.
% Data
x = 10;
idx = [12 20 15];
vdata = 1:100;
ind = repmat(-x:x,length(idx),1) + repmat(idx(:),1,2*x+1);
vdata(ind)