Lsqr first iteration with no initial guess - matlab

I am trying to solve
argmin||W_vector*FT^-1(Ax)-W_vector*B||
using lsqr with a function handle and without any initial guess (W_vector is a weighting vector). I thought that lsqr would have performed the first step computing x by C'b (call C=W*FT^-1(A)) using the vector b=W_vector.*B I passed to the function. This is the code:
b=W_vector.*B;
[x, flag]=lsqr(#(x1,modo)FUNC(x1,W_vector,A,modo),b,tol,maxit);
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_vector.*R3(:);
case 'transp'
R1=reshape(x1./(W_vector+eps),norient,dim(1)*dim(2)*dim(3));
for co=1:norient
R2(:,:,:,co)=reshape(R1(co,:),dim(1),dim(2),dim(3));
FR(:,:,:,co)=fftn(R2(:,:,:,co));
aux=FR(:,:,:,co);
R3(co,:)=aux(:).';
end
result=A'*R3(:);
end
end
When I checked the result of R1=reshape(x1./(W_vector+eps),norient,dim(1)*dim(2)*dim(3)); in case 'transp' in the first iteration, I found out that x1 is not equal to b (after reshape, they are images, so I can see that look qualitatively the same but with very different values). I would like to understand how lsqr works because I am having some problems with weightings. Thanks for your help.

Related

How to write a MATLAB code for this kind of Heaviside step function?

To solve one dimensional advection equation denoted by
u_t+u_x = 0, u=u(x,t), and i.c. u(x,0)= 1+H(x+1)+H(x-1)
using Lax Wanderoff method,
I need to write a Heaviside step function H(x) and it needs to be zero when x <= 0, 1 when x>0 . The problem is I also need to use that function writing H(x-t+1), H(x-t-1) as I will compare what I find by the exact solution:
u(x,t) =1 + H(x-t+1) -H(x-t-1)
Here, the "x" and "t" are vectors such that;
x=-5:0.05:5
t=0:0.05:1
I wrote the Heaviside step function as the following; however, I need it without the for loop.
L=length(x)
function H_X= heavisidefunc(x,L)
H_X=zeros(1,L);
for i= 1:L
if x(i)<= 0
H_X(i)=0;
else
H_X(i)=1;
end
end
end
I get "Dimensions must agree." error if I write
H_X3 = heavisidefunc(x-t+1,L);
H_X4 = heavisidefunc(x-t-1,L);
The Heavyside function is really easy to program in Matlab
Heavyside=#(x) x>= 0;
The easiest way to get rid of the dimensions must agree error is to transpose one of the vectors. This will cause Matlab to construct a matrix of length(x1) by length(x2)
Heavyside(x-t'+1);
I came up with a solution. My new Heaviside function is;
function H_X= heavisidefunc(x)
if x<= 0
H_X=0;
else
H_X=1;
end
end
The problem I had was because I was storing the output as a vector and it just complicated things.
Now,writing H(x-t+1), H(x-t-1) is easier. Just put "heavisidefunc(x(i)-t(j)-1)" and loop from 1 to the length of x and l in two loops. Thanks to everyone!

Fourier series graph generation from given coefficients an, bn in Matlab(Scilab)

I've calculated coefficients an, bn (100, T=2*pi) in c++ and checked that they are correct using few sources. Now i try to generate Fourier series graph for given example function in Scilab:
(x+2)*abs(cos(2*x*(x-pi/6)))
M=csvRead(filename, ";", [], 'double')
n=size(M,1)
for i = 1:n
A(i)=M(i)
B(i)=M(i + n)
end
function series=solution(x)
series=A(1)/2;
for i = 2:n
series=series+(A(i)*cos(i*x)+B(i)*sin(i*x));
end
endfunction
function series=solution2(x)
series=(x+2).*abs(cos(2.*x.*(x-%pi/6)));
endfunction
x = -%pi:%pi/100:%pi
plot2d(x, solution(x), 3)
x2 = -%pi:%pi/100:%pi
plot2d(x2, solution2(x2), 4)
Here is the result:
It clearly looks that tendency is ok but the beginning and the end of the period are wrong (reversed?). Do you see any issues in Scilab code? What could cause the problem - values in sin/cos in function solution(x)? Should i provide an, bn values and check for miscalculation there?
I don't know how did you calculated your A & B coefficients, but I assume that you used the usual notations to get the first line of the below formula:
Thus n starts from 1. Since Scilab starts vector indexing from 1, you correctly made your loop from 2, but forgot to compensate for this "offset".
Your function should be something like this:
function series=solution(x)
series=A(1)/2;
for i = 2:n
series=series+(A(i)*cos((i-1)*x)+B(i)*sin((i-1)*x));
end
endfunction
Since you didn't provided A & B, I can not check the result.
Additional note: Syntactically more correct if you explicitly define all input variables in a function, like this:
function series=solution(x,A,B)
This way you may be sure that your input is not changed somewhere else in the code.

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 solve a system of ordinary differntial equation with time-dependent parameters

How solve a system of ordinary differential equation ..an initial value problem ....with parameters dependent on time or independent variable?
say the equation I have
Dy(1)/dt=a(t)*y(1)+b(t)*y(2);
Dy(2)/dt=-a(t)*y(3)+b(t)*y(1);
Dy(3)/dt=a(t)*y(2);
where a(t) is a vector and b(t) =c*a(t); where the value of a and b are changing with time not in monotone way and each time step.
I tried to solve this using this post....but when I applied the same principle ...I got the error message
"Error using griddedInterpolant The point coordinates are not
sequenced in strict monotonic order."
Can someone please help me out?
Please read until the end to see whether the first part or second part of the answer is relevant to you:
Part 1:
First create an .m file with a function that describe your calculation and functions that will give a and b. For example: create a file called fun_name.m that will contain the following code:
function Dy = fun_name(t,y)
Dy=[ a(t)*y(1)+b(t)*y(2); ...
-a(t)*y(3)+b(t)*y(1); ...
a(t)*y(2)] ;
end
function fa=a(t);
fa=cos(t); % or place whatever you want to place for a(t)..
end
function fb=b(t);
fb=sin(t); % or place whatever you want to place for b(t)..
end
Then use a second file with the following code:
t_values=linspace(0,10,101); % the time vector you want to use, or use tspan type vector, [0 10]
initial_cond=[1 ; 0 ; 0];
[tv,Yv]=ode45('fun_name',t_values,initial_cond);
plot(tv,Yv(:,1),'+',tv,Yv(:,2),'x',tv,Yv(:,3),'o');
legend('y1','y2','y3');
Of course for the fun_name.m case I wrote you need not use sub functions for a(t) and b(t), you can just use the explicit functional form in Dy if that is possible (like cos(t) etc).
Part 2: If a(t) , b(t) are just vectors of numbers you happen to have that cannot be expressed as a function of t (as in part 1), then you'll need to have also a time vector for which each of them happens, this can be of course the same time you'll use for the ODE, but it need not be, as long as an interpolation will work. I'll treat the general case, when they have different time spans or resolutions. Then you can do something of the following, create the fun_name.m file:
function Dy = fun_name(t, y, at, a, bt, b)
a = interp1(at, a, t); % Interpolate the data set (at, a) at times t
b = interp1(at, b, t); % Interpolate the data set (bt, b) at times t
Dy=[ a*y(1)+b*y(2); ...
-a*y(3)+b*y(1); ...
a*y(2)] ;
In order to use it, see the following script:
%generate bogus `a` ad `b` function vectors with different time vectors `at` and `bt`
at= linspace(-1, 11, 74); % Generate t for a in a generic case where their time span and sampling can be different
bt= linspace(-3, 33, 122); % Generate t for b
a=rand(numel(at,1));
b=rand(numel(bt,1));
% or use those you have, but you also need to pass their time info...
t_values=linspace(0,10,101); % the time vector you want to use
initial_cond=[1 ; 0 ; 0];
[tv,Yv]= ode45(#(t,y) fun_name(t, y, at, a, bt, b), t_values, initial_cond); %
plot(tv,Yv(:,1),'+',tv,Yv(:,2),'x',tv,Yv(:,3),'o');
legend('y1','y2','y3');

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.