Reshaping MATLAB matrix in a particular way - matlab

I am working on a MATLAB code so that I can basically do this
To accomlish that, my code looks like this
A = [1:30]'; % Example matrix
rows = 3;
for i=1:(numel(A)-rows+1)
B(1:rows,i)=A(i:i+rows-1,1);
end
Can someone help me do the same in a simpler way? I am guessing there is a one-line command that can solve that (maybe I'm wrong).

Let A and rows be defined as in your code. I'm assuming the values in A are just an example. If they are always 1, 2, ..., some of the solutions below can be simplified.
A = [1:30].';
rows = 3;
Here are some approaches:
My choice:
B = A(bsxfun(#plus, (1:rows).', 0:numel(A)-rows));
An alternative:
B = conv2(A.', flip(eye(rows)));
B = B(:, rows:end-rows+1);
Slightly more inefficient:
B = hankel(A);
B = B(1:rows, 1:numel(A)-rows+1);
If you have the Image Processing Toolbox:
B = im2col(A, [rows 1], 'sliding');

Related

A for/while/if program to create a vector of repeated elements

My task is to write a program to create a vector which has its first 10 elements to be 10, element 11-20 to be 20, element 21-30 to be 30, element 31-40 to be 40, & element 41-50 to be 50.
This is how i did it.
v=zeros(1,50);
for i = 1:10
v(i)=10;
end
for i =11:20
v(i)=20;
end
for i = 21:30
v(i)=30;
end
for i = 31:40
v(i)=40;
end
for i = 41:50
v(i)=50
end
How can I write this more efficiently? (I'm new to matlab and programming in general. I'm thinking about how to construct this using while or if loops instead but without being able to produce a more efficient code.)
As we're spit-balling ways of doing this, something a bit different (though likely not efficient):
v=sort(mod(10:10:500,50))+10;
Also a method similar to rayryeng's answer, though I think slightly more efficient (avoiding the call to bsxfun):
v = 10:10:50;
v = v(ones(10,1),:);
v = v(:)';
The solutions in the comments as well as Shai's are very good. This is primarily here for thinking outside of the box. A more exotic solution would be to use bsxfun, followed by unrolling the resulting matrix into a vector:
v = bsxfun(#times, 10:10:50, ones(10,1));
v = v(:).';
The dedicated function for this task since Matlab R2015a is repelem:
x = repelem(10:10:50,10)
and another alternative:
s = 10; m = 50;
x = meshgrid(s:s:m,ones(s,1))
x = x(:)
You can use cumsum:
v = zeros(1,50);
v(1:10:end) = 10;
v = cumsum(v)
Using kron:
v = kron(10:10:50,ones(1,10))
If you like modulo operations, you can
v = reshape( mod(reshape((0:49)',[5 10]),5)'+1, 1, [] )*10
I suppose it's a bit more efficient that sort+mod proposed by #MrAzzaman.

What's the difference between two way to input Matlab Complex Matrices

Here's two ways to enter the command in Matlab. I don't think there's any difference between them. However, the result is really different. So I wonder what's I missed in this situation.
Here's the first input:
>> A = [(-0.025+0.01i) -0.025;
3 (1-2i)];
>> B = [(5.7955+1.5529i) 0]';
>> I=inv(A)*B
The output is like this:
I =
1.0e+02 *
-0.7063 - 1.2723i
-1.1030 + 1.6109i
Here's the second input:
>> A = [(-0.025+0.01i) -0.025;3 (1-2i)];
>> B = [(5.7955+1.5529i);0];
>> I=inv(A)*B
And the Matlab give me the result below:
I =
2.44764705882354 - 145.499411764706i
-176.067882352941 + 84.3624705882353i
I'm really confused about this situation. If you know anything please let me know about it. Thanks.
Use B = [(5.7955+1.5529i) 0].' which is actually element-wise transpose and not B = [(5.7955+1.5529i) 0]' which is conjugate transpose.
One can also use an explicit call to transpose command - B = transpose([(5.7955+1.5529i) 0])

Matlab: How to re-order (re-organize) a matrix

I have a random column matrix:
r = rand(1,300)';
I want to re-order it so that instead of having elements in the order of 1,2,3,...,300
I will have elements 1,11,21,31,...,291,2,12,22,32,...,292,3,13,33,...293,...,300.
In other words, I want to take every 10th value, beginning with 1 and put them in that order, then do the same for 2 with every 10th value. I know one way to do this is:
n = 10;
r = [r(1:n:numel(r)); r(2:n:numel(r)); r(3:n:numel(r));...;r(10:n:numel(r))]; % Skipped 4-9 in this example
But obviously, this is very cumbersome to do more than a couple of times. Is there something more efficient?
A loop should be easy, but I am not doing it correctly, it seems (I can see why this might not work, but I can't correct it).
(Here is what I tried:)
n = 10;
for i = 1:10
a = [r(i:n:numel(r))];
end
Any suggestions or help is greatly appreciated.
You can do it like this:
r = reshape(reshape(r, 10, 30)', 300, 1)
EDIT:
As pointed out by #LuisMendo on the comments, it's safer to use .' than ' to transpose the matrix, because if the matrix is complex, that could introduce a complex conjugation. Then, it would be safer to do it like this:
r = reshape(reshape(r, 10, 30).', 300, 1)
You could reshape it into 30x10 matrix, transpose, and take the flat index:
A = 1:300;
A = reshape(A,30,10);
A = A';
A = A(:);
Try this -
intv = 10; %%// Interval after which you intend to get the values consecutively
out = r(reshape(reshape(1:numel(r),intv,[])',1,[]))
Some of the other solutions posted are more efficient, but your idea was a good one. It requires a simple fix to work:
N = numel(r);
M = N/10;
a=[];
for ii = 1:M
a= [a r(ii:10:N)];
end
Hope this helps

classification with four classes by matlab

I have a classification problem with four classes of input vector.The four classes are
A = [1 , 1; 1 ,2];
B = [2,2; -1,0];
C = [-1,-2;2,1];
D = [-1,-2; -1,-2];
I wan Implement this problem by Matlab, I Use this code :
C = [-1,-2;2,1];
A = [1 , 1; 1 ,2];
B = [2,2; -1,0];
D = [-1,-2; -1,-2];
hold on
grid on
plot(A(1,:),A(2,:),'bs')
plot(B(1,:),B(2,:),'r+')
plot(C(1,:),C(2,:),'go')
plot(D(1,:),D(2,:),'m*')
a = [0 1]';
b = [1 1]';
c = [1 0]';
d = [0 0]';
P = [A B C D];
T = [repmat(a,1,length(A)) repmat(b,1,length(B)) repmat(c,1,length(C)) repmat(d,1,length(D)) ];
net = perceptron;
E = 1;
net.adaptParam.passes = 1;
linehandle = plotpc(net.IW{1},net.b{1});
n = 0;
while (sse(E))
n = n+1;
[net,Y,E] = adapt(net,P,T);
linehandle = plotpc(net.IW{1},net.b{1},linehandle);
drawnow;
end
but My Code does'nt work I have No idea why, please Help me....
As has been suggested by thewaywewalk, the trouble is your while-loop and the fact that you do not provide an adequate check for the statement you wish to evaluate.
Replace your while-statement with these two lines:
ACCEPTABLE_ERROR = 3.0;
while (sse(E)>ACCEPTABLE_ERROR)
And you should see your script terminate after three iterations. You can play with the ACCEPTABLE_ERROR variable to check which solution works best for you. If you set it too small, your while loop will not exit, because the statement will not be false.
An explanation to your original while-statement:
All you ever evaluated if sse(e) returned a results - which it did in each case. That's why it never stopped.
To the question of sse requires more than one input argument:
That depends on what input arguments you provide.
The documentation says:
perf = sse(net,t,y,ew) takes these input arguments and optional function parameters,
net: Neural network
t: Matrix or cell array of target vectors
y: Matrix or cell array of output vectors
ew: Error weights (default = {1})
and returns the sum squared error.
However, it is not necessary, to provide the error weights, ew, as the source code reveals:
Only the first three arguments are required. The default error weight is {1}, which weights the importance of all targets equally.
In your case you should, based on the documentation, call sse like this:
sse(net,T,Y)
Without being mentioned in the documentation (or I haven't found it), this is equivalent to what you have done, by providing simply the network errors, E as provided from adapt:
sse(E)
Both give the same results.

arrayfun when each row of the array is an input

My situation is that I would like to map a scalar array A by a function with handle fun sending a row vector to a row vector, to acquire B, such that B(i,:) = fun(A(i,:)).
The most reasonable solution I could think of looks like:
temp = mat2cell(A,ones(1,size(A,1)),size(A,2));
B = cell2mat(cellfun(fun,temp,'UniformOutput',0));
However, the conversion to cells and back seems like overkill (and is assumably computationally expensive). It is also not clear to me why cellfun complains about non-uniform output. Does a more efficient way jump to mind?
There's another solution that employs accumarray. Although not as fancy as bsxfun, it doesn't require declaring a helper function:
subs = ndgrid(1:size(A, 1));
B = accumarray(subs(:), A(:), [], #fun); %// #fun is the function handle
You can do this without using cell arrays at all with bsxfun.
Using Marcin's example data and function:
A =[ 0.5669 0.4315 0.4515 0.7664 0.5923; ...
0.8337 0.7317 0.4898 0.2535 0.7506; ...
0.3321 0.5424 0.4585 0.8004 0.9564];
fun = #(x,y) x*2;
B= bsxfun(fun,A,1);
B =
1.1338 0.8630 0.9030 1.5328 1.1846
1.6674 1.4634 0.9796 0.5070 1.5012
0.6642 1.0848 0.9170 1.6008 1.9128
Edit:
As Eitan noted, fun above may need to be a wrapper on your 'real' anonymous function so it would be more complete to show my solution as:
fun = #(x) x *2; % Replace with actual anonymous function
fun2 = #(x,y) fun(x); % Wrapper on fun to discard unused 2nd parameter
B= bsxfun(fun2,A,1);
I know this is an old post, but in case someone else sees this, Matlab added rowfun to the 2013b release which can evaluate rows of tables and returns a column vector. Here is an example:
f = #(c) sum(c.^2);
x=[1 2;
3 4;
5 6];
z=table2array(rowfun(f,table(x)))
z=
5
25
61
I think you could do as follows, if I understand what u want to do:
A = rand(3, 5);
fun = #(x) x*2;
B = cell2mat(arrayfun(#(i) fun(A(i, :)), 1:size(A, 1), 'UniformOutput', false)');
% example results:
A =
0.5669 0.4315 0.4515 0.7664 0.5923
0.8337 0.7317 0.4898 0.2535 0.7506
0.3321 0.5424 0.4585 0.8004 0.9564
B =
1.1338 0.8630 0.9030 1.5328 1.1845
1.6675 1.4635 0.9795 0.5071 1.5013
0.6642 1.0848 0.9169 1.6008 1.9128
This will apply fun to each element of row in A. This is based on the post here. Also there u find more info and explanation what is happening or alternative ways of applying function to rows in an array.