[Ifeffit] Re: Artemis question

Bruce Ravel ravel at phys.washington.edu
Wed Jan 21 12:51:47 CST 2004

On Wednesday 21 January 2004 12:22 pm, Daniel Carter wrote:
> Dear Bruce --
>        I've read as much material as I can find and I can't figure out how
> to use the restrain parameter in the Guess, Set, Def parameters window in
> Artemis.
> Say I want to limit Amp between 0.7 to 1.0, how do I do it?
> Do I use restrain or def and then what to I enter in the "Math Expressions
> field." I really need to find more info on what can be entered in math
> expr. field.
> Thanks, Dan Carter
>              Hunter College   NY, NY


I trust you won't mind if I answer your question on the Ifeffit
mailing list.  That way others can see the question and you might hear
words of wisdom from some of the gurus who hang out on the list.

As to what can be entered in the math expression field, well -- just
that.  Any valid math expression (which can be as simple as a number
or a complex combination of functions and infix binary operators) goes
in there.

If you "def" a parameter to be a number (e.g. def foo=5), that is the
same as setting it to a number (e.g. set foo=5)..

If you def a parameter to be a set parameter, i.e.
    set  a = 5
    def  b = a
that will, in effect, be the same as setting both a and b to 5,
although deffing parameters in this way can often be a pleasant
convenience at the user interface level.

Things get more interesting when you start using more extensive math
expressions.  Take this, for example:
    guess a = 0
    def   b = abs(a)
a will then float in the fit and may be positive or may be negative.
b will always be positive, but its value will depend on where a ends
up as a floating variable.

Another example.  Consider a mixed first shell with 6 atoms.  Further
suppose that about half of them are of atom X and the rest are atom
Y.  You might float an s02 variable and then use a weighting parameter
to adjust the relative amounts of atoms X and Y.

    guess  amp   = 0.9  # this is our s02 parameter
    guess  frac  = 0.5
    def    amp_x = amp * frac
    def    amp_y = amp * (1-frac)

You would then use amp_x and amp_y as the s02 path parameters when you
go define paths.  In the fit, both the s02 and the mixing fraction
would be determined.

Alright.... that gives you some sense of the kinds of math expressions
you can use.  Binary operators (+ - * / ^ for addition, subtraction,
multiplication, division, and exponentiation) are all available.  Many
functions (such as abs(), exp(), cos(), and so on) are also available.
See the Ifeffit manual on Matt's web site for the full list of

So, finally, I am going start answering your question about getting an
s02 value to come out between 0.7 and 1.0.  There are two ways,
constraints and restraints.

You can constrain (i.e. force) that parameter to be between those
values.  To do this you can use the standard min/max idiom.

    guess a = 0.9
    def   b = min( max(0.7, a), 1.0 )

Deconstruct that idiom by working from the inside out.  The "max(0.7,
a)" part forces b to be no smaller than 0.7.  If a drifts below 0.7, b
will then be pegged at 0.7.  The "min()" part does the same thing on
the other side.  If a is above 0.7, then b will equal a.  But if a
drifts above 1.0, then b will equal 1.0.

Using a constraint is fairly simple.  A bit more complicated is the
use of a restraint.  I trust that Matt or Scott will help me out if I
mis-state anything at this point.

The logic of a restraint is a bit different than a constraint.  With a
restraint, you want to penalize the fit if the value of the parameter
drifts too far away from some acceptable value.  So we will set the
restraint up in this way:

    guess    amp_guess  = 0.85
    set      amp_target = 0.85
    set      scale      = 100
    restrain amp        = abs(amp_guess - amp_target) * scale

So, what does this all mean?  Well, amp_guess is the floating
parameter which will, well, float during the fit.  amp_target is the
value that you think the amplitude should be.  I chose the midpoint of
your range for this example.  Before I explain scale and the actual
restraint, let's talk about how Matt implemented restraints in

Ifeffit decides on its set of best-fit values by minimizing a
statistical metric called chi-square.  This is essentially the sum of
the difference of squares between the data and the theory evaluated
only over the fitting range and normalized in a way that considers the
approximate amount of information left unused in the fit.  The
best-fit values are those that minimize chi-square.  When you use a
restraint, you add one more term to the quantity that is minimized
during the fit.  That is, the *sum* of chi-square and all of your
restraints are minimized.  Thus the restraint offers an incentive to
the fit to meet the criteria of the restraint (or, equivalently, a
penalty for not meeting the criteria), without forcing it to do so.
Probably, the sum of chi-square and the restraints will be minimized
when the constraint is minimized, but it is allowed for the guess
parameter upon which the restraint depends to drift away from the
restraining condition so long as the *sum* of chi-square and the
restraint is minimized.


So, in the math expressions above, I have made a restraint that gives
a penalty when the value of amp_guess drifts away from amp_target in
either direction.  The scale parameter is chosen to adjust the
importance of the restraint.  Since scale is a multiplicative
parameter, the restraint will be more important (in the context of
minimizing the sum of chi-square and the restraint) if scale is larger
and the restraint will be less important if scale is smaller.

How big should scale be?  Well that depends on how big chi-square is
for your fits and how strong of a restraint you actually want.
Basically the scale parameter lets you fine tune the importance of the

A word of caution.  Restraints can be dangerous.  Here is a quiz:  Why
is this definition of the restraint a bad idea?

      set      scale = -100
      restrain amp   = abs(amp_guess - amp_target) * scale

Finally, I never actually told you how to set up a restraint that
offers no penalty if the s02 is between 0.7 and 1.0 but to start
applying a penalty if it drifts out of that range.  I'm leaving that
as an exercise for the reader.  I am doing so largely because I can't
think of the answer off the top of my head. ;-)
Hope that helps and don't hesitate to ask more questions on the
mailing list in the future.


 Bruce Ravel  ----------------------------------- ravel at phys.washington.edu
 Code 6134, Building 3, Room 222
 Naval Research Laboratory                          phone: (1) 202 767 5947
 Washington DC 20375, USA                             fax: (1) 202 767 1697

 NRL Synchrotron Radiation Consortium (NRL-SRC)
 Beamlines X11a, X11b, X23b
 National Synchrotron Light Source
 Brookhaven National Laboratory, Upton, NY 11973

 My homepage:    http://feff.phys.washington.edu/~ravel 
 EXAFS software: http://feff.phys.washington.edu/~ravel/software/exafs/

More information about the Ifeffit mailing list