Generate multiple systems with a for loop

General forum for EasySpin: questions, how to's, etc.
Post Reply
thanasis
Local Expert
Posts: 245
Joined: Thu Jan 21, 2016 6:28 am
Location: Strasbourg

Generate multiple systems with a for loop

Post by thanasis »

Hello everyone,

I want to generate n spin systems, all of which are variants of a basic system according to a predefined trigonometric function. The fit is carried out on two external parameters that generate the actual parameters of each individual spin system.

My code is:

Code: Select all

cm=100*clight/1e6; % Conversion constant from cm-1 to MHz

J=-30; % Isotropic exchange in cm-1 according to the -2JSiSj formalism (external parameter)
r=0.01; % Coefficient (external parameter)
gxy=2; gz=2;
n=12; %Number of variations of the phi angle <--This is the number of the individual spin systems that will be generated

% Angles to be used as constants
theta1=0;
theta2=-2*pi/3;
theta3=2*pi/3;

%Experimental for curry
[T,chiSI] = textread('data_easyspin_chiSI.dat','%f %f');
Exp.Field = 1000; Exp.Temperature = T; chiSI = n*chiSI; <-- The calculated curves are added up. The experimental curve needs to be multiplied by [i]n[/i] to be brought up to the calculated curve.

%Define a dummy system containing the J and r parameters as variables
SysA.r = r;
SysA.J = J;

% Create n systems Sys(1), Sys(2),...Sys(n)
for i=1:n 
phi(i)=((i-1)/n)*2*pi;

%The trigonometric function:
a12(i)=r*(cos(phi(i)-theta1));
a13(i)=r*(cos(phi(i)-theta2));
a23(i)=r*(cos(phi(i)-theta3));

J12(i)=-2*cm*J*(1+a12(i));
J13(i)=-2*cm*J*(1+a13(i));
J23(i)=-2*cm*J*(1+a23(i));

Sys(i).S=[5/2 5/2 5/2];
Sys(i).g=[gxy gz; gxy gz; gxy gz];
Sys(i).weight=1/n;
Sys(i).ee = [J12(i) J13(i) J23(i)];
end

VaryA.r = [0.01];
VaryA.J = [5];
for i=1:n
    Vary(i).ee = [0 0 0];
    Vary(i).g = [0 0; 0 0; 0 0];
end

FitOpt.OutArg = [2 2];   % to fit the magnetic susceptibility chizz (second output)
FitOpt.Method = 'simplex fcn';
FitOpt.Scaling = 'none';

esfit('curry',chiSI,{SysA,Sys(1),Sys(2),Sys(3),Sys(4),Sys(5),Sys(6),Sys(7),Sys(8),Sys(9),Sys(10),Sys(11),Sys(12)},{VaryA,Vary(1),Vary(2),Vary(3),Vary(4),Vary(5),Vary(6),Vary(7),Vary(8),Vary(9),Vary(10),Vary(11),Vary(12)},Exp,[],FitOpt);
The code works up to a certain point. The fitting window comes up, the calculated curve is displayed for the initial values of the parameters, but the RMSD stays invariable despite the variation of J and r. In essence, there is no fit taking place.

What am I missing?

Thanks in advance!
joscha_nehrkorn
EasySpin Guru
Posts: 32
Joined: Wed Jan 20, 2016 11:35 am

Re: Generate multiple systems with a for loop

Post by joscha_nehrkorn »

You vary r and J, which do not affect the calculations done in curry. That's why no fitting take place.

You have to define a function which do the assignment of r and J to the subsystems and then call curry. Then you can call this function with esfit (read the manual on how to use esfit with self-written fit function).
thanasis
Local Expert
Posts: 245
Joined: Thu Jan 21, 2016 6:28 am
Location: Strasbourg

Re: Generate multiple systems with a for loop

Post by thanasis »

Thanks for the pointer Joscha, I will look into it!
thanasis
Local Expert
Posts: 245
Joined: Thu Jan 21, 2016 6:28 am
Location: Strasbourg

Re: Generate multiple systems with a for loop

Post by thanasis »

OK, so I took another look at the examples on the use of esfit with external functions.

One thing that I don't understand is how to deal with several Sys structures, like in my case. I have defined SysA which holds the two "dummy" variables and Sys(i) (i = 1,2,....n) which are the actual spin systems.

I tried building a function like:

Code: Select all

function y = myfun(SysA,Exp,Opt)
r=0;
J=0;
gz=2; gxy=2;
n=0;
theta1=0;
theta2=-2*pi/3;
theta3=2*pi/3;
cm=100*clight/1e6; % Conversion constant from cm-1 to MHz
SysA.r = r;
SysA.J = J;

for i=1:n 
phi(i)=((i-1)/n)*2*pi;

a12(i)=... etc
J12(i)=...etc

Sys(i).S=[5/2 5/2 5/2];
Sys(i).g=[gxy gz; gxy gz; gxy gz];
Sys(i).weight=1/n;
Sys(i).ee = [J12(i) J13(i) J23(i)];

Vary(i).ee = [0 0 0];
Vary(i).g = [0 0; 0 0; 0 0];
end
[x,y] = curry(SysA,Exp,Opt);
return
,
where I invoke only the "dummy" system SysA. Is that a valid approach?

I then found that I still need to define the Sys(i) systems with the for loop in my main code, otherwise I get an error for undefined variables. Then, when I invoke my function like so:

Code: Select all

esfit('myfun',chiSI,{SysA,Sys(1),Sys(2),Sys(3),...},VaryA,Vary(1),Vary(2),Vary(3),...},Exp,[],FitOpt);
When the fitting window comes up and I hit "Start", I get the error:

Code: Select all

Error using myfun
Too many output arguments.
What am I missing?
joscha_nehrkorn
EasySpin Guru
Posts: 32
Joined: Wed Jan 20, 2016 11:35 am

Re: Generate multiple systems with a for loop

Post by joscha_nehrkorn »

I doubt that there is any physical sense in what you want to try.

Anyhow, reread the manual to writing your own fit function and start with a way simpler example which you might be able to make it work. For example take the following: as you want to use curry, write a fit function which return chi *T in cgs units. After this you can go to more advanced things.
A few hints:
-when you define a fit function you should be able to call it without esfit and it should return reasonable results. Think about a case where you believe to know what the output should be
- think about where variables should be defined and how should they look like
- debug your code and watch values of variables
thanasis
Local Expert
Posts: 245
Joined: Thu Jan 21, 2016 6:28 am
Location: Strasbourg

Re: Generate multiple systems with a for loop

Post by thanasis »

I am resurrecting this thread to post an update of this work. The system we needed to treat (and the model we used) is described in http://pubs.acs.org/doi/abs/10.1021/acs ... em.6b01912. I particularly want to thank Stefan and Joscha for their helpful comments.

I had to make some custom fitting code to work around the fact that curry doesn't accept multiple systems. If this could be built into its functionality at some later stage, that would be really great!
Stefan Stoll
EasySpin Creator
Posts: 1073
Joined: Mon Jul 21, 2014 10:11 pm
Location: University of Washington

Re: Generate multiple systems with a for loop

Post by Stefan Stoll »

I see. We will add multi-system support for curry to our feature request list.
Stefan Stoll
EasySpin Creator
Posts: 1073
Joined: Mon Jul 21, 2014 10:11 pm
Location: University of Washington

Re: Generate multiple systems with a for loop

Post by Stefan Stoll »

The new version 5.1.9 has this implemented.Check it out.
Post Reply