include include include include include # IN_GFIT -- Fit a function using non-linear least squares. The function # can have an arbitrary number of independent variables. This is the main # entry point for the interactive part of the INLFIT package. procedure ing_fitd (in, gp, cursor, gt, nl, x, y, wts, names, npts, nvars, len_name, wtflag, stat) pointer in # INLFIT pointer pointer gp # GIO pointer char cursor[ARB] # GIO cursor input pointer gt # GTOOLS pointer pointer nl # NLFIT pointer double x[ARB] # independent variables (npts * nvars) double y[ARB] # dependent variables double wts[ARB] # weigths char names[ARB] # star ids int npts # number of points int nvars # number of variables int len_name # length of an object name int wtflag # type of weighting int stat # Error code (output) int i, wcs, key, gkey, newgraph int xtype, xvar, ytype, yvar, xt, xv, yt, yv double fit pointer sp, cmd, oldwts, help, prompt real wx, wy int gt_gcur1(), ing_nearestd(), in_geti() double nlevald() begin # Allocate string space. call smark (sp) call salloc (cmd, SZ_LINE, TY_CHAR) # Allocate and initialize a copy of the weights. A new copy # of the weights is used because it is necessary to have the # original values to restore them back when the user deletes # and undeletes points. call salloc (oldwts, npts, TY_DOUBLE) call amovd (wts, Memd[oldwts], npts) # Allocate space for help page and prompt, and get them. call salloc (help, SZ_LINE, TY_CHAR) call salloc (prompt, SZ_LINE, TY_CHAR) call in_gstr (in, INLHELP, Memc[help], SZ_LINE) call in_gstr (in, INLPROMPT, Memc[prompt], SZ_LINE) # Initialize INLFIT flags. call in_puti (in, INLOVERPLOT, NO) # Initialize loop control variables. The first action # is to fit the data, in order to have all the fit # parameters set. key = 'f' newgraph = YES # Get initial setup for axes. gkey = in_geti (in, INLGKEY) call in_gkey (in, gkey, INLXAXIS, xtype, xvar) call in_gkey (in, gkey, INLYAXIS, xtype, xvar) # Loop reading cursor commands. repeat { switch (key) { case '?': # Print help text. call gpagefile (gp, Memc[help], Memc[prompt]) case ':': # List or set parameters. if (Memc[cmd] == '/') call gt_colon (Memc[cmd], gp, gt, newgraph) else call ing_colond (in, Memc[cmd], gp, gt, nl, x, y, wts, names, npts, nvars, len_name, newgraph) case 'c': # Print the positions and useful info on data points. i = ing_nearestd (in, gp, gt, nl, x, y, npts, nvars, wx, wy) if (i != 0) { fit = nlevald (nl, x[(i-1)*nvars+1], nvars) call printf ( "%d %s x=%g y=%g func=%g fit=%g, resid=%g\n") call pargi (i) call pargstr (names[(i-1)*len_name+1]) call pargr (wx) call pargr (wy) call pargd (y[i]) call pargd (fit) call pargd (y[i] - fit) } case 'd': # Delete data points. call ing_deleted (in, gp, gt, nl, x, y, wts, npts, nvars, wx, wy) case 'f': # Fit the function. # Fit. do i = 1, npts { if (wts[i] > double(0.0)) wts[i] = Memd[oldwts+i-1] } call in_fitd (in, nl, x, y, wts, npts, nvars, wtflag, stat) newgraph = YES case 'g': # Set graph axistype types. call ing_defkey (in, nvars, newgraph) case 'h': if (in_geti (in, INLGKEY) != 1) { call in_puti (in, INLGKEY, 1) newgraph = YES } case 'i': if (in_geti (in, INLGKEY) != 2) { call in_puti (in, INLGKEY, 2) newgraph = YES } case 'j': if (in_geti (in, INLGKEY) != 3) { call in_puti (in, INLGKEY, 3) newgraph = YES } case 'k': if (in_geti (in, INLGKEY) != 4) { call in_puti (in, INLGKEY, 4) newgraph = YES } case 'l': if (in_geti (in, INLGKEY) != 5) { call in_puti (in, INLGKEY, 5) newgraph = YES } case 'o': # Set the overplot flag. call in_puti (in, INLOVERPLOT, YES) case 'r': # Redraw the graph. newgraph = YES case 't': # Toggle overplot fit flag. if (in_geti (in, INLPLOTFIT) == YES) call in_puti (in, INLPLOTFIT, NO) else call in_puti (in, INLPLOTFIT, YES) newgraph = YES case 'u': # Undelete data points. call ing_undeleted (in, gp, gt, nl, x, y, wts, Memd[oldwts], npts, nvars, wx, wy) case 'w': # Window graph. call gt_window (gt, gp, cursor, newgraph) case 'I': # Interrupt. call fatal (0, "Interrupt") default: # Let the user decide on any other keys. call ing_ufit (in, gp, gt, nl, wx, wy, wcs, key, Memc[cmd]) } # Redraw the graph if necessary. if (newgraph == YES) { gkey = in_geti (in, INLGKEY) call in_gkey (in, gkey, INLXAXIS, xt, xv) if (xt != xtype || xv != xvar) { call in_gkey (in, gkey, INLXAXIS, xtype, xvar) call gt_setr (gt, GTXMIN, INDEFR) call gt_setr (gt, GTXMAX, INDEFR) } call in_gkey (in, gkey, INLYAXIS, yt, yv) if (xt != xtype || xv != xvar) { call in_gkey (in, gkey, INLYAXIS, ytype, yvar) call gt_setr (gt, GTYMIN, INDEFR) call gt_setr (gt, GTYMAX, INDEFR) } call ing_graphd (in, gp, gt, nl, x, y, wts, npts, nvars) newgraph = NO } if (cursor[1] == EOS) break } until (gt_gcur1 (gt, cursor, wx, wy, wcs, key, Memc[cmd], SZ_LINE) == EOF) # Free memory. call sfree (sp) end