Improper assignment with rectangular empty matrix 0 - matlab

???Improper assignment with rectangular empty matrix
Error in task3, 18
y(:,1)=log(r);
The error persists and I don't know what to do.
The script is given below
function task3
time=xlsread('Kinetics_data.xls','B3:B82');
Conc=xlsread('Kinetics_data.xls','C3:C82');
CAo=0.050;
CBo=0.0406;
h=0.5;
n=length(Conc);
%Calculate the reaction rate using the forward difference equation and
%eliminate outliners if necessary.
global CA CB
t=time(2:n-1);
CA=Conc(2:n-1);
CB=CBo-(CAo-CA);
r=(-Conc(3:n)+Conc(1:n-2))/(2*h);
y(:,1)=log(r);
X(:,1)=ones(size(CA));
X(:,2)=log(CA);
X(:,3)=log(CB);
[b bint resid residint stats]=regress(y,X);
b;
bint;
k=exp(b(1));
kint=exp(bint(1,:));
b(1)=k;
% Set initial guess of parameter value.
m0=b;
% Set lower and upper bounds for the parameters
ub=[2.981770068869469 1.515475186852946 0.914563691229481];
lb=[1.354032677809809 0.938815382572068 0.753329300963922];
options=optimset('TolX',1e-16,'TolFun',1e-16,'MaxFunEval',4000,'MaxIter',4000);
[m,residn,resid,exiflage,output,lamda,Jacob]=lsqcurvefit(#ratefun,m0,t,r,lb,ub,options)
end

Hint
I can easily reproduce your error by setting $n=0$ at the top of your script so think about the reason why $n=0$ in your case (further hint: check your excel file for the range of the data)

Related

Noise cancellation with fft failing - unable to assign elements

I have the following code for noise cancellation:
[z,fs] = audioread('noisy_voices.wav'); % Use >>soundsc(z, fs) to hear the unprocessed signal
zproc_vec=zeros(1,length(z));
tail = zeros(1,256);
for k = 0:128:length(z)-256
Z = fft(z(k +1:k + 256).* hann(256));
[zmax, zl] = max(abs(Z(1:128)));
Z(zl-3: zl +3)=0;
Z(256-(zl-3:zl +3)+2)=0;
zproc = ifft(Z);
zproc = zproc+tail;
tail(1:128) = zproc(129:256);
zproc_vec(k+1:k+256)=zproc;
end
soundsc(zproc_vec , fs)
Could anyone tell me why I get this error?
Unable to perform assignments because the left and right sides have a different number of elements
Error in task_one (line 12)
zproc_vec(k+1:k+256)=zproc;
I think the output of your Z = fft( ___ ) line will be a column vector, but you initialise tail to be a row vector with tail = zeros(1,256);
So on this line:
zproc = zproc+tail;
Implicit expansion would make zproc a square 256*256 matrix.
Then your indexing fails, as specified by the error message, because you're trying to assign this square matrix to the 256 elements you're indexing with zproc_vec(k+1:k+256).
Initialising tail to a column vector should solve the issue.
Alternatively you could take the "lazy" way out and make sure you're only operating on column vectors to create zproc
zproc = zproc(:)+tail(:); % Make both terms column vectors for addition
''Unable to perform assignments because the left and right sides have a different number of elements''
What part of the error message do you not understand? It means that the variables on the left and the right side of the equal sign have different sizes so you can't assign the right thingy to the left thingy.
Check the sizes and make sure they are the same.

lsqr result strongly depends on weights

I need to solve:
argmin||W*FT^-1(Ax)-W*p||
using lsqr. p is image, x is k-space matrix, A is a matrix and W is a weighting matrix. In order to pass them to matlab lsqr, I vectorized p, x and W.
This is my code:
b=W.*p;
x=lsqr(#(x1,modo)FUNC(x1,W_vector,A,modo),b,tol,maxit);
X_k_lsqr=reshape(x,dim(1),dim(2),dim(3));
X_lsqr=real(ifftn(X_k_lsqr)).*MASK(:,:,:,1);
%% Auxiliary function
function [result modo]=FUNC(x1,W_vector,A,modo)
%Computes y=A*x for modo='notransp'
%Computes y=A'*x for modo='transp'
switch modo
case 'notransp'
res=A*x1;
R1=reshape(res,norient,dim(1)*dim(2)*dim(3));
for co=1:norient
R2(:,:,:,co)=reshape(R1(co,:),dim(1),dim(2),dim(3));
FR(:,:,:,co)=ifftn(R2(:,:,:,co));
aux=FR(:,:,:,co);
R3(co,:)=aux(:).';
end
result=W.*R3(:);
case 'transp'
RR1=reshape(x1./(W+eps),norient,dim(1)*dim(2)*dim(3));
for co=1:norient
RR2(:,:,:,co)=reshape(RR1(co,:),dim(1),dim(2),dim(3));
FRR(:,:,:,co)=fftn(RR2(:,:,:,co));
aux=FRR(:,:,:,co);
RR3(co,:)=aux(:).';
end
result=A'*RR3(:);
end
end
As W appears in both terms of the minimization problem, I would have expected the image I obtain as a result to be almost independent on W values.
The image looks qualitatively the same if I change W, but its values strongly depend on W. I don't know if something is wrong with my code.
Should I actually obtain almost the same values for different W?
A question: Have you checked the flag? Are you sure that you are using the results while the flag is 0?
An argument: I can assume W also as a switch that determines which components of p I want to minimize. If W*(Ax-b) is really equal to 0, then you are right but here we know that there is not an exact solution and it becomes W*(Ax-b) < W*tolerance. So, you are depending the end point of the algorithm on the elements of W together with the tolerance.

How to plot this function in matlab

The problem is how to plot the below equation in discrete form:
g=(1-exp(-1i*pi*k))/(1-exp(-1i*pi*k/50)) where k ranges from -300 to 300
When I execute the program I always get the following error:
"Attempted to access (-299); index must be a positive integer or logical."
I don't really know what it means, I tried to exclude the even value of pi but still the same problem. I need a hand here please.
try:
clear all
k = -300:300;
g = (1-exp(-1i*pi*k))./(1-exp(-1i*pi*k/50));
subplot(3,1,1)
plot(k,real(g))
ylabel('real(g)')
xlabel('k')
subplot(3,1,2)
plot(k,imag(g))
ylabel('imag(g)')
xlabel('k')
subplot(3,1,3)
plot(g)
xlabel('real(g)')
ylabel('imag(g)')
I'm affraid you could have overriden exp and this caused a problem

MATLAB - understanding structure of Event location function

In my textbook I have encountered an example of a function I am supposed to use when specifying an event location for a system of ODEs. The function example is as follows:
function [value, isterminal, dircn] = proj(t,z,flag);
g = 9.81;
if nargin < 3 | isempty(flag)
value = [z(2); 0; z(4); -g];
else
switch flag
case 'events'
value = z(3);
isterminal = 1;
dircn = -1;
otherwise
error('function not programmed for this event');
end
end
There is one part of the logic here which I don't understand. Say that I activate the "events" option and then run ode45. How, then, can ode45 actually read the system of equations (which is specified in the above function as value = [z(2); 0; z(4); -g];)? I have ran ode45 based on the above function, after specifying tspan and inital conditions of course, and it works like a charm. But I don't understand how ode45 can read the system properly when it is only presented in the "if"-part of the script above.
If anyone can explain the logic here, I would greatly appreciate it!
Well I think I can explain some parts. As I wrote above it is strange that the dimension of value changes.
given your statespace and the names of your variables it looks like 2 dimensional motion.
in the case of no flag it seems that state space is:
horizontal position (x)
horizontal speed (vx)
vertical position (y)
vertical speed (vy)
correction
It seems that ode can send 'events' when you specify them. So your function outputs 3rd component of the state space. Look at this site explaining it: http://www.mathworks.de/help/techdoc/math/f1-662913.html
unless you specify it beforehand ode can't send 'events' to the function so this part will not be called.
But your function won't work anyway - as the derivative would need to have same dimension as the statespace (4x1). But has only 1x1.
But I really don't know what you mean by "specifying an event location". Maybe the secret is hidden there.
With some creativity I think you could use the function to extract the 3rd component of the state space.
The answer is in the if command:
if nargin < 3 | isempty(flag)
value = [z(2); 0; z(4); -g];
else
If number of arguments is less than 3 or if variable flag is empty, then set variable value to [z(2); 0; z(4); -g]. Otherwise, if variable flag is 'events', then set variable value to z(3), and when flag is not 'events', report an error. So this function always assigns some return value for variable value or, reports an error using error command.
I can supplement a bit more information about how we proceed after writing the function above. We then define, say:
tspan = [0 6];
z0 = [0, 5*cos(pi/4), 0, 5*sin(pi/4)];
options = odeset('events','on');
[t y] = ode42('proj',tspan,z0,options)
By writing this the output is 5 columns, 1 column for tspan , and 1 column for each of the z-values (z(1), z(2), z(3) and z(4)). When z(3) hits zero, the calculations are terminated since the "event" occurs.
If, on the other hand I do not include the options = odeset('events','on') line, and simply write:
[t y] = ode42('proj',tspan,z0)
The calculations are performed for the entire tspan range.
Yet, I still fail to see how ode42 is capable of calculating all the output vectors when we activate "events" since it then looks logical me that MatLab should only execute the "else"-statement in the "proj"-function. And in this part of the function, the actual system of the differential equations is not included.

Metropolis algorithm in MATLAB -->> error with function handles

i have a piece of metropolis algorithm:
mB=5.79*10^(-9); %Bohr magnetone in eV*G^-1
kB=0.86*10^(-4); %Boltzmann in eV*K^-1
%system parameters
L=60; %side square grid
L2=L*L; % total number grid position
Tstep=5; %step in temperature change (K)
Maxstep=10; %max number of steps
nmcs=5; % cycle numberof Metropolis algorithm
magnet=NaN(1,Maxstep);%store magnetization in "monte carlo images" of sample
%Creation initial point arrangement of magnetic spins
%Outer parameters
H=100000; %Gauss
T=20; % Kelvin
%Energy alteration in spin-reverse
de =# (i,j) (2*mB*H).*mlat(i,j);
%Metropolis probability
pmetro=# (i,j) exp(-de(i,j)./(kB*T));
%Creation and display of initial lattice
mlat=2*round(rand(L,L))-1;
mtotal=sum(mlat(:))./L2
% Alteration of system with time
for ii=1:Maxstep
for imc=1:nmcs
for i=1:L
for j=1:L
if pmetro(i,j)>=1
mlat(i,j)=-mlat(i,j);
elseif rand<pmetro(i,j)
mlat(i,j)=-mlat(i,j);
end
end
end
end
magnet(:,ii)=sum(mlat(:))./L2;
%figure(ii);
%pcolor(mlat);
% shading interp;
end
m1=mean(magnet)
error=std(magnet) ./sqrt(numel(magnet))
fprintf('Temperature = %d K',T)
figure(13)
plot(magnet(1,:),'b.')
axis([0 10 0 0.5])
grid on
xlabel('i (Configuration) ')
ylabel('M/(N*mB)')
Now,the problem is in figure(13).The values it gives me are around zero (0.05,0.02..).It supposes to give me values around 0.3..
Generally,the graph its ok,It gives me the right "shape"(it has points) but as i said around zero.
I really don't know how to put this post in order to be understood.Maybe i have some mistake in the "magnet"matrix ,i don't know.
Anyway,i don't demand from anybody to check it thoroughly ,i am just asking if with a quick look anyone can help.
ΕDIT--->> Also,sometimes when i run the program ,it gives me :
Undefined function or method 'mlat'
for input arguments of type 'double'.
Error in ==> #(i,j)(2*mB*H).*mlat(i,j)
Error in ==>
#(i,j)exp(-de(i,j)./(kB*T))
Error in ==> metropolis at 39
if pmetro(i,j)>=1
EDIT--->>> I found the "mistake" .In my code in the loops where i have the function "pmetro" i replaced it with the "exp(-(2*mB*H).*mlat(i,j)./(kB*T))" and the program worked just fine!!!
Why it didn't work with calling the "pmetro"??How can i overcome this?Is there a problem with function handles in loops?
Blockquote
I very strongly suggest that you try writing code without using any function handles until you're really familiar with Matlab.
The line
de =# (i,j) (2*mB*H).*mlat(i,j);
is what causes your problems. In Matlab, when you define a function handle that refers to, say, an array, the function handle will use the array as it was at the time of definition. In other words, even though mlat changes inside your loop, mlat(i,j) inside the function de is always the same. In fact, you cannot even run this code unless you have previously defined mlat in the workspace.
You should therefore rewrite the main loop as follows
for iStep = 1:maxStep
for imc = 1:mcs
pmetro = $some function of mlat - this can be calculated using the
entire array as input
%# for each element in mlat (and thus pmetro), decide whether
%# you have to switch the spin
switchIdx = pmetro > 1 | pmetro < rand(size(mlat));
mlat(switchIdx) = -mlat(switchIdx);
end
$calculate magnetization$
end
Also, note that there is a command mean to take the average. No need to sum and then divide by the number of elements.