Delete the last row of a table - Matlab - matlab

How can I delete the last row of a table based (if it will have a changing length)?
Code:
clc;
clear all;
close all;
x = 1:10
y =11:20
lastrow = length(x);
t = table(x,y)
t([lastrow,:) = [];

You can use the end function to access the last row or column.
I think you wanted to create a 10 by 2 table. If you want to do so, you should define x and y as a column vector, not a row vector.
clc;
clear all;
close all;
x = (1:10)';
y =(11:20)';
% lastrow = length(x);
t = table(x,y);
t(end,:) = [];
disp(t)

Related

Animating 3D Random Walk Matlab

I am writing a code to simulate random walk in 3D space on Matlab. However, there seems to be a problem with my number of simulations, M. I want to animate multiple simulations on the same graph but I am only get 1 simulation. My input of M instead becomes the number of steps. How can I fix this code? Thank you.
I want it to look like the animation in this video: https://www.youtube.com/watch?v=7A83lXbs6Ik
But after each simulation is complete, another one starts on the same graph but a different color.
The end result should be like this
final
clc;
clearvars;
N = input('Enter the number of steps in a single run: '); % Length of the x-axis and random walk.
M = input('Enter the number of simulation runs to do: '); % The number of random walks.
x_t(1) = 0;
y_t(1) = 0;
z_t(1) = 0;
for m=1:M
for n = 1:N % Looping all values of N into x_t(n).
A = sign(randn); % Generates either +1/-1 depending on the SIGN of RAND.
x_t(n+1) = x_t(n) + A;
A = sign(randn); % Generates either +1/-1 depending on the SIGN of RAND.
y_t(n+1) = y_t(n) + A;
A = sign(randn);
z_t(n+1) = z_t(n) + A;
end
plot3([x_t(1) x_t(n+1)], [y_t(1) y_t(n+1)], [z_t(1) z_t(n+1)], 'g');
hold on
grid on
x_t = x_t(n+1);
y_t = y_t(n+1);
z_t = z_t(n+1);
drawnow;
end
You are plotting in the wrong place:
clc;
clearvars;
N = 100
M = 5
x_t(1) = 0;
y_t(1) = 0;
z_t(1) = 0;
c=lines(M) % save colors so each m has its own
for m=1:M
for n = 1:N % Looping all values of N into x_t(n).
A = sign(randn); % Generates either +1/-1 depending on the SIGN of RAND.
x_t(n+1) = x_t(n) + A;
A = sign(randn); % Generates either +1/-1 depending on the SIGN of RAND.
y_t(n+1) = y_t(n) + A;
A = sign(randn);
z_t(n+1) = z_t(n) + A;
plot3([x_t(n) x_t(n+1)], [y_t(n) y_t(n+1)], [z_t(n) z_t(n+1)],'color',c(m,:));
hold on
grid on
drawnow;
end
end

Count the number of unique values for each column of a submatrix in a fast manner

I have a matrix X with tens of rows and thousands of columns, all elements are categorical and re-organized to an index matrix. For example, ith column X(:,i) = [-1,-1,0,2,1,2]' is converted to X2(:,i) = ic of [x,ia,ic] = unique(X(:,i)), for convenient use of function accumarray. I randomly selected a submatrix from the matrix and counted the number of unique values of each column of the submatrix. I performed this procedure 10,000 times. I know several methods for counting number of unique values in a column, the fasted way I found so far is shown below:
mx = max(X);
for iter = 1:numperm
for j = 1:ny
ky = yrand(:,iter)==uy(j);
% select submatrix from X where all rows correspond to rows in y that y equals to uy(j)
Xk = X(ky,:);
% specify the sites where to put the number of each unique value
mxj = mx*(j-1);
mxi = mxj+1;
mxk = max(Xk)+mxj;
% iteration to count number of unique values in each column of the submatrix
for i = 1:c
pxs(mxi(i):mxk(i),i) = accumarray(Xk(:,i),1);
end
end
end
This is a way to perform random permutation test to calculate information gain between a data matrix X of size n by c and categorical variable y, under which y is randomly permutated. In above codes, all randomly permutated y are stored in matrix yrand, and the number of permutations is numperm. The unique values of y are stored in uy and the unique number is ny. In each iteration of 1:numperm, submatrix Xk is selected according to the unique element of y and number of unique elements in each column of this submatrix is counted and stored in matrix pxs.
The most time costly section in the above code is the iterations of i = 1:c for large c.
Is it possible to perform the function accumarray in a matrix manner to avoid for loop? How else can I improve the above code?
-------
As requested, a simplified test function including above codes is provided as
%% test
function test(x,y)
[r,c] = size(x);
x2 = x;
numperm = 1000;
% convert the original matrix to index matrix for suitable and fast use of accumarray function
for i = 1:c
[~,~,ic] = unique(x(:,i));
x2(:,i) = ic;
end
% get 'numperm' rand permutations of y
yrand(r, numperm) = 0;
for i = 1:numperm
yrand(:,i) = y(randperm(r));
end
% get statistic of y
uy = unique(y);
nuy = numel(uy);
% main iterations
mx = max(x2);
pxs(max(mx),c) = 0;
for iter = 1:numperm
for j = 1:nuy
ky = yrand(:,iter)==uy(j);
xk = x2(ky,:);
mxj = mx*(j-1);
mxk = max(xk)+mxj;
mxi = mxj+1;
for i = 1:c
pxs(mxi(i):mxk(i),i) = accumarray(xk(:,i),1);
end
end
end
And a test data
x = round(randn(60,3000));
y = [ones(30,1);ones(30,1)*-1];
Test the function
tic; test(x,y); toc
return Elapsed time is 15.391628 seconds. in my computer. In the test function, 1000 permutations is set. So if I perform 10,000 permutation and do some additional computations (are negligible comparing to the above code), time more than 150 s is expected. I think whether the code can be improved. Intuitively, perform accumarray in a matrix manner can save lots of time. Can I?
The way suggested by #rahnema1 has significantly improved the calculations, so I posted my answer here, as also requested by #Dev-iL.
%% test
function test(x,y)
[r,c] = size(x);
x2 = x;
numperm = 1000;
% convert the original matrix to index matrix for suitable and fast use of accumarray function
for i = 1:c
[~,~,ic] = unique(x(:,i));
x2(:,i) = ic;
end
% get 'numperm' rand permutations of y
yrand(r, numperm) = 0;
for i = 1:numperm
yrand(:,i) = y(randperm(r));
end
% get statistic of y
uy = unique(y);
nuy = numel(uy);
% main iterations
mx = max(max(x2));
% preallocation
pxs(mx*nuy,c) = 0;
% set the edges of the bin for function histc
binrg = (1:mx)';
% preallocation of the range of matrix into which the results will be stored
mxr = mx*(0:nuy);
for iter = 1:numperm
yt = yrand(:,iter);
for j = 1:nuy
pxs(mxr(j)+1:mxr(j),:) = histc(x2(yt==uy(j)),binrg);
end
end
Test results:
>> x = round(randn(60,3000));
>> y = [ones(30,1);ones(30,1)*-1];
>> tic; test(x,y); toc
Elapsed time is 15.632962 seconds.
>> tic; test(x,y); toc % using the way suggested by rahnema1, i.e., revised function posted above
Elapsed time is 2.900463 seconds.

Is there a way to vectorize this loop in MATLAB?

I wish to vectorize this for loop. This loop is about getting the coordinates of image pixels and form an array in a row by row order.
rows = 812; % 812x650 image
cols = 650;
n=rows*cols; % total number of pixels
index = zeros(n,2); % n coordinates of image pixels
pt_homo = zeros(3,1,n); % [x,y,1]'
k=1;
for r=1:rows
for c=1:cols
index(k,1)=c;
index(k,2)=r;
pt_homo(1,1,k) = c;
pt_homo(2,1,k) = r;
pt_homo(3,1,k) = 1;
k=k+1;
end
end
So if i understand your question correctly this should solve it
c = 1:cols;
r = 1:rows;
[X Y] = meshgrid(r,c);
index = [Y(:) X(:)];
pt_homo_ = permute([index ones(size(index,1),1)],[2 3 1]);
Basically what i did is create the index vectors and create a matrix of indexes using meshgrid and then reorder it to be in the format you wanted.

Weird thing with matlab's plotting

When I execute this plot function trying to plot my data as a solid red line it will not plot anything.
plot(1:n, exp(x), '-r')
However, if I change the specification from a solid red line to a green line of circles still using the exact same data as so,
plot(1:n, exp(x), 'og')
it will plot! Why??
Here is all the code if needed.
clear all;
close all;
fprintf('\n\nJustin White Th-9\n\n')
x = input('Input the value of x to be approximated: ');
se = input('Input the target approximate perecent relative error, se: ');
[apre, macexp, n] = f_macexpF15(x, se);
macexp = macexp(1:end-1);
plotyy( 1:n, macexp, 1:n, apre);
hold on;
plot(1:n, exp(x), '-r')
And function it calls here
function[apre, macexp, n] = f_macexpF15(x, se)
fprintf('\nJustin White Th-9\n')
apre = 100*ones(1,3);
ms = [36 22 10];
macexp(1) = 1;
j = 1;
n = 1;
%% comments
while apre >= se
macexp(j+1) = macexp(j) + x^j/factorial(j);
apre(j) = 100 * ((macexp(j+1)-macexp(j))/macexp(j+1));
j = j + 1;
n = n + 1;
end
n = n - 1;
end
Thanks in advance
Easy, 1:n is a vector of length n, whereas x is only a scalar value if not entered correctly. So first of all check whether or not both vectors (1:n and x) are of same size.
Why? If you have two entries for the plot command, and one entry is a vector and the other is a scalar, then MATLAB treats that as if you entred n different plot commands (n for the length of the vector).

MATLAB: Multiple occurences data in the pdist function: how?

MATLAB: we have data that give x y coordinates of occurences. Often there are more then 1 occurences on one location. This generates a problem when we want to use this data in the function pdist. We tried to change the data into a list with x y coordinates for EACH occurence, but havent managed so far. Does anyone have a solution for this?
% initial values m = 0;
[X,Y,People,Positive] = textread('Loaloa_data.txt', '%f%f%f%f', 'headerlines', 1);
LoaData = [X,Y,People, Positive];
%calculate percentage of infected people per location
Percentage_per_Location = (Positive(:)./People(:))*100;
%calculate percentage of total infected people per location
TotPos = sum(Positive);
Percentage_of_Total = Positive(:)./TotPos*100;
LoaData = [X,Y,People,Positive,Percentage_per_Location, Percentage_of_Total];
%Make a new frequency table in which every value of Positive has a x and y
%value.
% first make a new matrix with x and y coordinated and positive values.
LengthColumn = (1:197)';
Matrix1 = [LengthColumn,X,Y,Positive];
Freq = zeros(sum(Positive(:)),2) ;
% r = Matrix1(:,1)
% CumFreq = ([1: sum(Positives)]);
% Freq = Matrix1(:,4);
% xyData =zeros(length(Freq),2);
for i=1:length(Matrix1(:,1))
%for m<=TotPos
F = Matrix1(i,4)
for j =[1:F]
m = m+j
Freq(m,1:2) = Matrix1(i,2:3)
end
% end
end