/* Minuit		by Paul Kunz	May 1993
 * Encapsulator of Minuit Fortran
 *
 * Copyright (C)  1993  The Board of Trustees of
 * The Leland Stanford Junior University.  All Rights Reserved.
 */

#import "Minuit.h"

const char Minuit_h_rcsid[] = MINUIT_H_RCSID;
const char Minuit_m_rcsid[] = "$Id: Minuit.m,v 1.3 1993/07/29 06:13:47 rensing Exp $";

#import "string.h"
#import "minuit89.h"     /* Minuit common block and function prototypes */
#import "minuitFCN.h"

@implementation Minuit

- init
{
    int lunRd = 0, lunWr = 6, lunSave = 0;
    
    [super init];
    mninit_(&lunRd, &lunWr, &lunSave, 0, 0, 0);
    return self;
}
- clearParms
{
    mncler_();
    return self;
}
- doFitWith:(FCNParms *)fcnParms
{
    void 	(*fcnptr)() = fcn_;
    char 	prtCmd[] = "SET PRINTOUT";
    char 	minCmd[] = "MINIMIZE";
    double 	arglist[3];
    int 	nargs = 0;
    int		irc;
    
  /* set print level */
    arglist[0] = 2.0;
    nargs = 1;
#ifdef F2C
    mnexcm_( fcnptr, prtCmd, arglist, &nargs, &irc, fcnParms,
	    strlen(prtCmd) );
#else
    mnexcm_(&fcnptr, prtCmd, arglist, &nargs, &irc, fcnParms,
	    0,    strlen(prtCmd),    0,        0,      0,    0);
#endif

    arglist[0] = 10000.0;
    nargs = 1;
#ifdef F2C
    mnexcm_( fcnptr, minCmd, arglist, &nargs, &irc, fcnParms,
	     strlen(minCmd) );
#else
    mnexcm_(&fcnptr, minCmd, arglist, &nargs, &irc, fcnParms,
	    0,    strlen(minCmd),    0,        0,      0,    0);
#endif
    return self;
}
- getParms:(fitParm *)parm at:(int) index
{
    extern struct mn7err_t 	MN7ERR;
    char	chnam[10];
    double	val, err, bnd1, bnd2;
    int		ivarbl;
    
#ifdef F2C
    mnpout_( &index, chnam, &val, &err, &bnd1, &bnd2, &ivarbl,
		    10 );
#else 
    mnpout_( &index, chnam, &val, &err, &bnd1, &bnd2, &ivarbl,
		0,    10,    0,    0,     0,     0,       0 );
#endif
    parm->value       = val;
    parm->lower_error = val + MN7ERR.ern[index];  // MINOS errors 
    parm->upper_error = val + MN7ERR.erp[index];  // from common block.
    parm->error       = err;
    parm->upper_limit = val + err;
    parm->lower_limit = val - err;
    return self;
}
- setParms:(fitParm *)parm at:(int)iparm
{
    char	name[11];
    double 	stepSize;
    double	lower, upper;
    int		irc;
    
    sprintf( name, "%-10.10s", parm->name );
    if (parm->fixedValue)
	stepSize = 0.0;
    else
	stepSize = parm->step_size;
    if (parm->fixedLimits)
    {
	lower = parm->lower_limit;
	upper = parm->upper_limit;
    }
    else
    {
	lower = 0.0;
	upper = 0.0;
    }
#ifdef F2C
    mnparm_(&iparm, name, &parm->value, &stepSize,
	    &lower, &upper, &irc, 10 );
#else
    mnparm_(&iparm, name, &parm->value, &stepSize,
	    &lower, &upper, &irc, 0, 10, 0, 0, 0, 0, 0 );
#endif
    return self;
}
- setLagrangeAt:(int)iparm
{
    double 	value  = 1.0;
    double	stepSize = 0.1;
    double	lower = 0.0, upper = 0.0;
    int		irc;

#ifdef F2C
    mnparm_(&iparm, "Lagr.Mult.", &value, &stepSize,
	    &lower, &upper, &irc,  10 );
#else
    mnparm_(&iparm, "Lagr.Mult.", &value, &stepSize,
	    &lower, &upper, &irc, 0, 10, 0, 0, 0, 0, 0 );
#endif
    return self;
}
@end
