determine dimension of matrix under some conditions - matlab

suppose that we have matrix with size mXn, and i want to return matrix which contains elements of original matrix at odd indices,i wrote function which is called odd_index, for instance here is code
function B=odd_index(M);
% M- is given matrix
% purpose of this code is to return elements at odd indices
[m,n]=size(M);% calculate dimensions of matrix
B=[];%initialize matrices
% let run loops
i=1;
for k=1:m
for l=1:n
if (mod(k,2)==1 && mod(l,2)==1)
B(k,i)=M(k,l);
i=i+1;
end
end
end
B=B(B>0);
B=reshape(B,2,2);
end
for instance
(1,1,),(1,3),(3,1),(1,5),(5,1),(3,5),(5,3),(3,3),(5,5),(1,7)
and so on, what will be dimension of such matrix? i think it will be (m-2)X(n-4) but i am not sure about this and please could you help me?

solution will be by help of # Divakar
M(1:2:end,1:2:end)

Related

Encoding system of differential equations into a vector and approximate solutions

I am trying to solve a system of differential equations by the Euler's method. First, I have encoded my system into a vector. Then I pass the initial conditions to the function ode_Euler.
However, there's somehting wrong about my attempt. I am getting this error:
>> nm06p03a
Unable to perform assignment because the size of the left side is 1-by-2 and the size of the right side is 2-by-2.
Error in ode_Euler (line 11)
y(k+1,:)= y(k,:) +h*feval(f,t(k),y(k,:));
Error in nm06p03a (line 12)
tic, [tE,xE]=ode_Euler(f,tspan,x0,N); t_Euler=toc;
This is my code so far:
clear, clf
f=#(t,x)[-x(2)+x(1)*x(2); x(1)-(0.5.*x(1).^2)+(0.5.*x(2).^2)]; %Encoding system of differential equations into a vector
t0=0; tf=10;
tspan=[t0 tf];
N=100;
x0s=[0.2 0]; % A matrix consisting of initial points
for iter=1:size(x0s,1)
x0=x0s(iter,:);
tic, [tE,xE]=ode_Euler(f,tspan,x0,N); t_Euler=toc;
subplot(220+iter),
plot(tE,xE,'r:')
legend('ode_ Euler')
end
Here is the Euler's method:
function [t,y]=ode_Euler(f,tspan,y0,N)
if nargin<4|N<=0, N=100; end
if nargin<3, y0=0; end
h=(tspan(2)-tspan(1))/N;
t=tspan(1)+[0:N]'*h;
y(1,:)=y0(:)'; %make it a row vector
for k=1:N
y(k+1,:)= y(k,:) +h*feval(f,t(k),y(k,:));
end
When I use this other method ode_Heun, I get the same error:
function [t,y]=ode_Heun(f,tspan,y0,N)
if nargin<4|N<=0, N=100; end
if nargin<3, y0=0; end
h=(tspan(2)-tspan(1))/N; % Step-size
t=tspan(1)+[0:N]'*h; % Time vector
y(1,:)=y0(:)'; % make the initial value a row vector
for k=1:N
fk= feval(f,t(k),y(k,:)); y(k+1,:)= y(k,:)+h*fk; % Eq.(6.2.3)
y(k+1,:)= y(k,:) +h/2*(fk +feval(f,t(k+1),y(k+1,:))); % Eq.(6.2.4)
end
Can I get some help to understand the problem with my code?
y(k,:) is a row vector, while the return value of f is a column vector. Per broadcasting rules the sum of a row and a column vector is a matrix as the sum of the matrices of repeated row and column vectors.
This is not very logical in the context of vector and matrix operations, but can make sense in the processing of (finite) sequences of vectors. Unfortunately that distinction is not realized and enforced in the type system.

Problem in 2D heat equation solution using FDM in Matlab

I am trying to solve the 2D time dependent heat equation using finite difference method in Matlab. The code is below:
%Spatial variable on x direction
Lx=1;
delta=0.1;
xmin=-Lx/2;
xmax=Lx/2;
Nx=(xmax-xmin)/delta;
x=linspace(xmin,xmax,Nx);
%Spatial variable on y direction
Ly=1;
delta=0.1;
ymin=-Ly/2;
ymax=Ly/2;
Ny=(ymax-ymin)/delta;
y=linspace(ymin,ymax,Ny);
%Total matrix size
N = (Nx * Ny);
%Time variable
dt=0.002;
tmin=0;
tmax=1;
nt=(tmax-tmin)/dt;
tspan=linspace(tmin,tmax,nt);
%Create a meshgrid
[X,Y] = meshgrid(x,y);
% Defining initial state:
T0=exp(-(X.^2+Y.^2));
%reshape the initial condition to a vector
T_reshape = reshape(T0,N,1);
% Constructing the 1D spatial matrix
A=zeros(N,N);
I = eye(N);
%the diagonal elements
for m=1:N %the number of rows
for n=1:N %the number of columns
if (m==n)
A(m,n)=-2/delta^2;
end
%Boundary conditions: A(1,N)==A(N,1)
if(n==N)&&(m==1)
A(m,n)=1;
end
if(n==1)&&(m==N)
A(m,n)=1;
end
end
end
%the off-diagonal elements
for n=1:N-1
A(n+1,n)=1/delta^2; %the value of each lower off-diagonal elements
end
for n=2:N
A(n-1,n)=1/delta^2; %the value of each upper off-diagonal element
end
%create the 2D matrix
B = kron(A,I)+kron(I,A);
% Solve the equation
[Time,Tem]=ode45('dTDistribution',tspan,T_reshape,[],B,delta);
The function that is being called here is as following:
%Define the function
function dT=dTDistribution(tspan,T_reshape,dummy,B,delta)
dT = B.*T_reshape;
end
My problem is that the dimension of my matrix B is different than the dimensions of the initial condition T_reshape, therefore, the multiplication of B.*T_reshape won't be possible. I'm wondering how can I change the dimension of T_reshape to make the multiplication valid. Hope anyone could help.
Thank you.
Thank you for looking at my problem, but I have figured out the mistake in the code. Since A is the 1D matrix, then its size should be either (Nx,Nx) or (Ny,Ny) and then when taking the tensor product to get B the 2D matrix its size will be (N,N). However in the code, A has the size of (N,N) and as a result B is blowing up making the multiplication afterwards not possible.
Thanks.

How to raise a matrix to a vector of powers in matlab without for loop?

I have a 2x2 matrix that I want to multiply by itself 10 times while storing the result after each multiplication. This can easily be done with a for loop but I would like to vectorize it an eliminate the for loop. My approach was to have my 2x2 matrix a and raise it to a vector b with elements 1:10. The answer should be a 2x2x10 matrix that replicates typing
a^b(1)
a^b(2)
.
.
.
a^b(10)
To clarify I'm not doing this element wise I need actual matrix multiplication, and prefer not to use a for loop. Thanks for any help you can give me.
here is the code for you. I use the cellfun to do this and I have comments after each line of the code. It can compute and store from fisrt - nth order of the self-multiplication of an arbitrary matrix m. If you have any question, feel free to ask.
function m_powerCell = power_store(m, n) %m is your input matrix, n is the highest power you want to reach
n_mat = [1:n]; %set a vector for indexing each power result in cell
n_cell = mat2cell(n_mat,1,ones(1,n)); %set a cell for each of the power
m_powerCell = cellfun(#(x)power(m, x), n_cell, 'uni', 0); %compute the power of the matrix
end
%this code will return a cell to you, each element is a matrix, you can
%read each of the matrix by m_powerCell{x}, x represents the xth order

rewrite the seqneighjoin function in matlab

I have the task to rewrite the seqneighjoin function in matlab by adding the frequency of all the sequences. After searching, I understand that this function returns a phylogenetic tree object obtained by seqences neighbor joinn method from the wiki http://en.wikipedia.org/wiki/Neighbor_joining
Now, I have the following two questions.
(1): what is the data structure of this phytree object obtained by this function? How to express it? For example, for the similar linkage function, it also returns a phylogenetic tree, and the data structure is very clear there, i.e., it is a matrix with three columns, where the i-th column indicates which nodes are combined and the corresponding distance when they are combined. Thanks very much for your time and attention.
(2): Based on wiki, how am I supposed to add frequency to the function seqneighjoin? I am totally confused.
Thanks so much for your time and attention. I truly appreciate that.
EDIT: the following is the code.
function z = seqneighjoin(D_all, freq)
n = size (D_all, 2);
m=(1+sqrt(8*n+1))/2;
z=zeros(m-1,3);
q=zeros(m,m);
str = zeros (m,m);
% initialize the distance matrix d
d=ones(m,m);
d(tril(d,-1)==1)=D_all;
d(triu(d,1)==1)=D_all;
d(eye(m,m)==1) = 1:m; % the diagonal entries of the matrix d is the indices of the clusters
% initialize the matrix str
for r=1:m
for c=1:m
str(r,c)=freq(r)*freq(c)*d(r,c);
str(c,r)=freq(r)*freq(c);
end
end
% loop through for m-1 times to create the matrix z
for k = 1:m-1
% initialize (for the first time) or update (for all other times)
% the matrix q
colSum = sum(d, 1);
rowSum=sum(d,2);
a=size(colSum, 2);
colSumM=colSum(ones(a,1),:);
rowSunM=rowSum(:,ones(1,a));
q=(a-2)*d-colSumM-rowSumM;
% find the minimum element in the matrix q
u=min(q);
v=min(u);
[i,j]=find(q==v);
r=i(1);
c=j(1);
% combine d(r,r) and d(c,c) to get a new node m+k
z(k,:)=[d(r,r), d(c,c), v];
% calculate the distance between the new node m+k and all other node
% which are not m+k
d(r,:) = (d(r,:) + d(c,:) - d(r,c) )/2;
d(r,r) = m+k;
d(c,:)=[]; d(:,c)=[];
end
Here, D_all is the vector representation of a distance matrix returned by the seqpdist function in matlab, and freq is the vector indicating the frequency of all the sequences.

Matlab vectorizing equations and matrix multiplication

I have a program that currently uses a for loop to iterate through a set of functions. I've tried using parfor but that only works on the university's version of Matlab. I'd like to vectorize the handling of this so that a for loop isn't necessary. The equations I'm using basically call different types of Bessel functions and are contained in separate functions.
Here's what I'm trying to do:
For each value of m, build a vector of matrix elements for each required matrix. Then build each full matrix. I think this is working correctly.
Where it's throwing an error is on the final matrix multiplication... even if I just multiply the left 2x2 by the middle 2x2 I get the dreaded error:
??? Error using ==> mtimes
Inner matrix dimensions must agree.
Error in ==> #(m)CL(m)*CM(m)*CR(m)
% Vector for summation. 1 row, 301 columns with data from 0->300
m_max=301;
m=[0:m_max-1];
% Build the 300 elements for the left 2x2 matrix.
CL_11=#(m) H1(m,alpha1);
CL_12=#(m) H2(m,alpha1);
CL_21=#(m) n1*dH1(m,alpha1);
CL_22=#(m) n1*dH2(m,alpha1);
% Build the 300 elements for the middle 2x2 matrix.
CM_11=#(m) n1*dH2(m,alpha2);
CM_12=#(m) -1*H2(m,alpha2);
CM_21=#(m) -1*n1*dH1(m,alpha2);
CM_22=#(m) H1(m,alpha2);
% Build the 300 elements for the right 2x1 matrix.
CR_11=#(m) J(m,alpha3);
CR_21=#(m) n2*dJ(m,alpha3);
% Build the left (CL), middle (CM) and right (CR) matrices.
CL=#(m) [CL_11(m) CL_12(m);CL_21(m) CL_22(m)];
CM=#(m) [CM_11(m) CM_12(m);CM_21(m) CM_22(m)];
CR=#(m) [CR_11(m);CR_21(m)];
% Build the vector containing the products of each triplet of
% matrices.
C=#(m) CL(m)*CM(m)*CR(m);
cl=CL(m)
cm=CM(m)
cr=CR(m)
c=CL(m)*CM(m)*CR(m)
If you have any suggestions or recommendations, I'd greatly appreciate it! I'm still a newbie with Matlab and am trying to develop a higher level of ability with use of matrices and vectors.
Thanks!!
Your matrices are not 2x2. When you do CL_11(m) with m a 1x300 vector, CL_11(m) will be 1x300 as well. Thus CL(m) is 2x301. To get around this, you have to calculate the matrices one-by-one. There are two approaches here.
c=arrayfun(C,m,'UniformOutput',false)
will return a cell array, and so c{1} corresponds to m(1), c{2} to m(2), etc.
On the other hand, you can do
for i=1:m_max
c(:,:,i)=C(m(i));
end
and then c(:,:,i) corresponds to m(1), etc.
I'm not sure which version will be faster, but you can test it easily enough with your code.
If you go through the symbolic toolbox you can construct a function that is easier to handle.
%% symbolic
CL = sym('CL',[2,2])
CM = sym('CM',[2,2])
CR = sym('CR',[2,1])
r = CL*CM*CR
f = matlabFunction(r)
%% use some simple functions so it can be calculated as example
CL_11=#(m) m+1;
CL_12=#(m) m;
CL_21=#(m) m-1;
CL_22=#(m) m+2;
CM_11=#(m) m;
CM_12=#(m) m;
CM_21=#(m) 2*m;
CM_22=#(m) 2*m;
CR_11=#(m) m;
CR_21=#(m) 1-m;
%% here the substitution happens:
fh = #(m) f(CL_11(m),CL_12(m),CL_21(m),CL_22(m),CM_11(m),CM_12(m),CM_21(m),CM_22(m),CR_11(m),CR_21(m))
Out of interest I did a small speed test:
N=1e5;
v = 1:N;
tic
% .... insert symbolic stuff from above
r1 = fh(v);
t1=toc % gives 0.0842s for me
vs
CL=#(m) [CL_11(m) CL_12(m);CL_21(m) CL_22(m)];
CM=#(m) [CM_11(m) CM_12(m);CM_21(m) CM_22(m)];
CR=#(m) [CR_11(m);CR_21(m)];
C=#(m) CL(m)*CM(m)*CR(m);
tic
r2 =arrayfun(C,v,'UniformOutput',false);
t2=toc % gives 7.6874s for me
and
tic
r3 = nan(2,N);
for i=1:N
r3(:,i)=C(v(i));
end
t3=toc % 8.1503s for me