Getting the Row Matrix - matlab

I want to convert a n*n matrix into its respective row matrix in Matlab. How to achieve this ?
For example assume the original matrix is
7.0000 26.0000 6.0000 60.0000 78.5000
1.0000 29.0000 15.0000 52.0000 74.3000
11.0000 56.0000 8.0000 20.0000 104.3000
and I want to get the output as
7.0000 26.0000 6.0000 60.0000 78.5000 1.0000 29.0000 15.0000
52.0000 74.3000 11.0000 56.0000 8.0000 20.0000 104.3000
which is the row matrix.

As you want to reshape it into a vector, reshape might be a bit overkill, as you can just use linear indexing.
A = randi(10,5,5); %Create some matrix
B=A.'; %SLOW
B = B(:).'; %matrix -> vector conversion
On the other hand, the speed of the matrix -> vector conversion does not really matter as it is the initial transpose which is slow, which you'll need for any method, see e.g. Phil's answer.

Easiest solution is:
Anew = reshape(Aold',1,numel(Aold));
Of particular importance is that you need to use the transpose of Aold.

I think what you want is:
reshape(A, 1, []);
where A is your matrix. For example:
A = rand(5,5);
b = reshape(A, 1, []);
will give you a 1x25 matrix.

Suppose your original matrix is A (which has 15 elements)
A = [7.0000 26.0000 6.0000 60.0000 78.5000;
1.0000 29.0000 15.0000 52.0000 74.3000;
11.0000 56.0000 8.0000 20.0000 104.3000]
Now what you need is to reshape A to become a row vector.
reshape(A,1,[]) % Here 1 means you need one row, and [] means you need is as vector
If you want column vector you may use the following
reshape(A,[],1) % this gives a column vector
However, according to your objective the following code will do the job
A = [7.0000 26.0000 6.0000 60.0000 78.5000;
1.0000 29.0000 15.0000 52.0000 74.3000;
11.0000 56.0000 8.0000 20.0000 104.3000];
reshape(A,1,[])
The output will be
ans =
7.0000 1.0000 11.0000 26.0000 29.0000 56.0000 6.0000 15.0000 8.0000 60.0000 52.0000 20.0000 78.5000 74.3000 104.3000
For detailed information, type the following in the command window
help reshape

Related

Operations within matrix avoiding for loops

I have a rather simple question but I can't get the proper result in MATLAB.
I am writing a code in Matlab where I have a 200x3 matrix. This data corresponds to the recording of 10 different points, for each of which I took 20 frames.
This is just in order to account for the error in the measuring system. So now I want to calculate the 3D coordinates of each point from this matrix by calculating an average of the measured independent coordinates.
An example (for 1 point with 3 measurements) would be:
MeasuredFrames (Point 1) =
x y z
1.0000 2.0000 3.0000
1.1000 2.2000 2.9000
0.9000 2.0000 3.1000
Point = mean(MeasuredFrames(1:3, :))
Point =
1.0000 2.0667 3.0000
Now I want to get this result but for 10 points, all stored in a [200x3] array, in intervals of 20 frames.
Any ideas?
Thanks in advance!
If you have the Image processing toolbox blockproc could be an option:
A = blockproc(data,[20 3],#(x) mean(x.data,1))
If not the following using permute with reshape works as well:
B = permute(mean(reshape(data,20,10,3),1),[2,3,1])
Explanation:
%// transform data to 3D-Matrix
a = reshape(data,20,10,3);
%// avarage in first dimension
b = mean(a,1);
%// transform back to 10x3 matrix
c = permute(b,[2,3,1])
Some sample data:
x = [ 1.0000 2.0000 3.0000
1.1000 2.2000 2.9000
0.9000 2.0000 3.1000
1.0000 2.0000 3.0000
1.1000 2.2000 2.9000
0.9000 2.0000 3.1000
1.0000 2.0000 3.0000
1.1000 2.2000 2.9000
0.9000 2.0000 3.1000
1.1000 2.2000 2.9000]
data = kron(1:20,x.').';
A = B =
1.5150 3.1200 4.4850
3.5350 7.2800 10.4650
5.5550 11.4400 16.4450
7.5750 15.6000 22.4250
9.5950 19.7600 28.4050
11.6150 23.9200 34.3850
13.6350 28.0800 40.3650
15.6550 32.2400 46.3450
17.6750 36.4000 52.3250
19.6950 40.5600 58.3050
If you do not have access to the blockproc function, you can do it with a combination of reshape:
np = 20 ; %// number of points for averaging
tmp = reshape( A(:) , np,[] ) ; %// unfold A then group by "np"
tmp = mean(tmp); %// calculate mean for each group
B = reshape(tmp, [],3 ) ; %// reshape back to nx3 matrix
In your case, replace A by MeasuredFrames and B by Points, and group in one line:
Points = reshape(mean(reshape( MeasuredFrames (:) , np,[] )), [],3 ) ;
Matrix multiplication can be used:
N=20;
L=size(MeasuredFrames,1);
Points = sparse(ceil((1:L)/N), 1:L, 1)*MeasuredFrames/N;

Adding data in intervals in Matlab

Hi I have data in MATLAB like this:
F =
1.0000 1.0000
2.0000 1.0000
3.0000 1.0000
3.1416 9.0000
4.0000 1.0000
5.0000 1.0000
6.0000 1.0000
6.2832 9.0000
7.0000 1.0000
8.0000 1.0000
9.0000 1.0000
9.4248 9.0000
10.0000 1.0000
I am looking for a way to sum the data in specific intervals. Example if I want my sampling interval to be 1, then the end result should be:
F =
1.0000 1.0000
2.0000 1.0000
3.0000 10.0000
4.0000 1.0000
5.0000 1.0000
6.0000 10.0000
7.0000 1.0000
8.0000 1.0000
9.0000 10.0000
10.0000 1.0000
i.e data is accumulated in the second column based on sampling the first row. Is there a function in MATLAB to do this?
Yes by combining histc() and accumarray():
F =[1.0000 1.0000;...
2.0000 1.0000;...
3.0000 1.0000;...
3.1416 9.0000;...
4.0000 1.0000;...
5.0000 1.0000;...
6.0000 1.0000;...
6.2832 9.0000;...
7.0000 1.0000;...
8.0000 1.0000;...
9.0000 1.0000;...
9.4248 9.0000;...
10.0000 1.0000];
range=1:0.5:10;
[~,bin]=histc(F(:,1),range);
result= [range.' accumarray(bin,F(:,2),[])]
If you run the code keep in mind that I changed the sampling interval (range) to 0.5.
This code works for all sampling intervals just define your wanted interval as range.
Yes and that's a job for accumarray:
Use the values in column 1 of F to sum (default behavior of accumarray) the elements in the 2nd column.
For a given interval of size s (Thanks to Luis Mendo for that):
S = accumarray(round(F(:,1)/s),F(:,2),[]); %// or you can use "floor" instead of "round".
S =
1
1
10
1
1
10
1
1
10
1
So constructing the output by concatenation:
NewF = [unique(round(F(:,1)/s)) S]
NewF =
1 1
2 1
3 10
4 1
5 1
6 10
7 1
8 1
9 10
10 1
Yay!!

implementing "not equal to " loop in matlab

i have a simple problem i am quite new to matlab so i am having problem in implementing it i have two 64x2 matrices u and h.i have to check if a single row in u is not equal to all of the rows in h.then the row which is not equal should be saved in a separate matrix meanwhile i have written this code but what it does is that r(i,:) get all the values of u(i,:) when this code runs, what i want is that only those values of u(i,:) should be stored in r which are not similar to any row in h matrix.
h=[];
for j=1:8
for i=1:8
h=[h; i j];
end
end
u=[5.3,1.4;6,8;2,3;3,5.5;2.6,8;3.7,2;4,2;5,3;1.9,8;5.4,4;3.2,3;2,2;2,4;2,3;8,2.2;8,4;7.3,1.5;6.2,5.1;2.4,1.5;3,5;2,7.1;1.8,2.7;3,4;6,5;6,1;5,4;4,6;3.5,2;5,7;7.2,8;7,7;5,5;6,3;6,6;1,2;5,8;3,5;1,5;2,2;2,1;6,3;4,7;6,8;3,6;1,6;5,2;3,5;8,7;8,4;4,8;1,1;6,3;7,5;8,1;1,6;4,5;5,5;6,7;6,7;6,7;6,3;3,4;5,7;1,1]
for i=1
for j=1:64
if u(i,:)==h(j,:)
c=1
else
c=0
if c==0
r(i,:)=u(i,:)
end
end
end
end
can anyone help me please
You can do it in one line with ismember:
r = u(~ismember(u,h,'rows'),:);
With your example data, the result is
>> r
r =
5.3000 1.4000
3.0000 5.5000
2.6000 8.0000
3.7000 2.0000
1.9000 8.0000
5.4000 4.0000
3.2000 3.0000
8.0000 2.2000
7.3000 1.5000
6.2000 5.1000
2.4000 1.5000
2.0000 7.1000
1.8000 2.7000
3.5000 2.0000
7.2000 8.0000
use setdiff with 'rows' option to compute r. Please avoid unnecessary loops. pre-allocate when possible.
% construct h without loop
[h{1} h{2}]=ndgrid(1:8,1:8);
h=[h{1}(:) h{2}(:)];
% get r using setdiff
r = setdiff( u, h, 'rows')
Results with
r =
1.8000 2.7000
1.9000 8.0000
2.0000 7.1000
2.4000 1.5000
2.6000 8.0000
3.0000 5.5000
3.2000 3.0000
3.5000 2.0000
3.7000 2.0000
5.3000 1.4000
5.4000 4.0000
6.2000 5.1000
7.2000 8.0000
7.3000 1.5000
8.0000 2.2000
Solution of you question in NlogN complexity (N=64):
N=size(h,1);
[husorted,origin_husorted,destination_hu]=unique([h;u],'rows','first');
iduplicates=destination_hu(N+1:end)<=destination_hu(N),:);
r=u;
r(iduplicates,:)=0;
destination_uh is the only output of unique that is useful; It verifies [h;u]=husorted(destination_uh,:)]. 'first' ensures that if line i of u is equal line j of h, then destination_uh(i+N) is equal to destination_uh(j).
Solution for your particular h, with complexity N:
r=u;
r(all(u==round(u)&u>=1&u<=8,2),:)=0;

error with factorial.m function, getting non negative matrix error

I have the following vector,
N=10
vec=-N:1:N
and when running the command
factorial((N+vec)/2))
I am getting the error
??? Error using ==> factorial at 17
N must be a matrix of non-negative integers.
when "(N+vec)/2" is just
ans =
0 0.5000 1.0000 1.5000 2.0000 2.5000 3.0000 3.5000 4.0000
4.5000 5.0000 5.5000 6.0000 6.5000 7.0000 7.5000 8.0000 8.5000
9.0000 9.5000 10.0000
no negative numbers...
any trick to get around it?
thank you!
As wakjah stated in his comment, your problem is that when you divide by 2 in performing (N+vec)/2, you're getting non-integral numbers. You can do something like
factorial(round((N+vec)/2))
to round your factorial input values to their nearest integer values. Other rounding alternatives are floor to round down, and ceil to round up

Indexing during assignment

Say I have this sample data
A =
1.0000 6.0000 180.0000 12.0000
1.0000 5.9200 190.0000 11.0000
1.0000 5.5800 170.0000 12.0000
1.0000 5.9200 165.0000 10.0000
2.0000 5.0000 100.0000 6.0000
2.0000 5.5000 150.0000 8.0000
2.0000 5.4200 130.0000 7.0000
2.0000 5.7500 150.0000 9.0000
I wish to calculate the variance of each column, grouped by class (the first column).
I have this working with the following code, but it uses hard coded indices, requiring knowledge of the number of samples per class and they must be in specific order.
Is there a better way to do this?
variances = zeros(2,4);
variances = [1.0 var(A(1:4,2)), var(A(1:4,3)), var(A(1:4,4));
2.0 var(A(5:8,2)), var(A(5:8,3)), var(A(5:8,4))];
disp(variances);
1.0 3.5033e-02 1.2292e+02 9.1667e-01
2.0 9.7225e-02 5.5833e+02 1.6667e+00
Separate the class labels and the data into different variables.
cls = A(:, 1);
data = A(:, 2:end);
Get the list of class labels
labels = unique(cls);
Compute the variances
variances = zeros(length(labels), 3);
for i = 1:length(labels)
variances(i, :) = var(data(cls == labels(i), :)); % note the use of logical indexing
end
I've done a fair bit of this type of stuff over the years, but to be able to judge, better vs. best, it would help to know what you expect to change in the data set or structure.
Otherwise, if no change is anticipated and the hard code works, stick with it.
Easy, peasy. Use consolidator. It is on the file exchange.
A = [1.0000 6.0000 180.0000 12.0000
1.0000 5.9200 190.0000 11.0000
1.0000 5.5800 170.0000 12.0000
1.0000 5.9200 165.0000 10.0000
2.0000 5.0000 100.0000 6.0000
2.0000 5.5000 150.0000 8.0000
2.0000 5.4200 130.0000 7.0000
2.0000 5.7500 150.0000 9.0000];
[C1,var234] = consolidator(A(:,1),A(:,2:4),#var)
C1 =
1
2
var234 =
0.035033 122.92 0.91667
0.097225 558.33 1.6667
We can test the variances produced, since we know the grouping.
var(A(1:4,2:4))
ans =
0.035033 122.92 0.91667
var(A(5:8,2:4))
ans =
0.097225 558.33 1.6667
It is efficient too.