[Ifeffit] Re: Artemis question

Matt Newville newville at cars.uchicago.edu
Thu Jan 22 10:57:05 CST 2004

Hi Bruce,

I agree with most of your answer to Dan about setting constraints 
and restraints, but I think I'd fail the 'quiz' you gave:

> 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

where you had 
>     guess    amp_guess  = 0.85
>     set      amp_target = 0.85
>     set      scale      = 100
>     restrain amp        = abs(amp_guess - amp_target) * scale
as a recommended way to set just such a constraint. I believe 
there's no difference.  Am I missing something?

The sign of the restraint's value won't matter, and
     restrain amp    = 100 * (amp_guess - amp_target)

would be equivalent to both of the above.  The restraint's value is
jsut another element of the array of 'misfit', can be negative, and
the fit will attempt to bring the restraint close to zero.

> 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. ;-)

It's not pretty, but I think this will effectively set penalties for 
going above and below some value:

 guess  target   = 0.8

 set    lo_val   = 0.7
 set    up_val   = 1.0
 set    scale    = 100.0
 def    penalty  = (max((target-lo_val), abs(target-lo_val)) - 
                    min((target-up_val),-abs(target-up_val)) + 
                    lo_val - up_val)*scale

This penalty could then be used as a restraint.  Whereas contraints
give an infinite penalty for going above some value, this allows the
target value to fall outside the desired range, but gives a finite
penalty that increases linearly as with 'distance' from the desired
range. Setting just a  lower or upper bound would go like this:

  lower_penalty =  max((target-lo_val), abs(target-lo_val))-(target-lo_val)
  upper_penalty = -min((target-up_val),-abs(target-up_val))+(target-up_val)

To visualize this, an array of penalties can be plotted v. value 
(with scale set to 1):

  lo_val   = 0.7
  up_val   = 1.0
  target   = 0.8

  # array of target values
   m.vals = range(0,2,0.05)

  m.lower_p =  max((m.vals-lo_val), abs(m.vals-lo_val))-(m.vals-lo_val)
  m.upper_p = -min((m.vals-up_val),-abs(m.vals-up_val))+(m.vals-up_val)

  m.penalty = (max((m.vals-lo_val), abs(m.vals-lo_val)) - 

  newplot m.vals, m.penalty, style=linespoints2
  plot    m.vals, m.lower_p
  plot    m.vals, m.upper_p


More information about the Ifeffit mailing list