/**************************************************************************\ * These two subroutines together duplicate the entire fitpars structure. * * The second subroutine duplicates just a single object completely, and * * the first subroutine simply links them together. * \**************************************************************************/ #include #include #include "nrutil.h" #include "structs.h" struct fitpars *dup_fitpars_struct (struct fitpars *fpar) { struct fitpars *dup_one_obj (struct fitpars *fpar); struct fitpars *new, *head; int i; new = dup_one_obj (fpar); head = new; while (fpar->next != NULL) { fpar = fpar->next; new->next = dup_one_obj(fpar); new = new->next; }; new = head; return (new); } /************************************************************************\ * Duplicate a single object completely, from the classical parameters * * down to all the high order correction terms. The higher order list * * branches off the main structure in "fpar->high". The main structure * * stores all the classical parameters, and are connected through * * "fpar->next". But otherwise, both "fpar->high" and "fpar->next" * * use the same identical structure format. * * * * Setting the 'high' flag to 1, tells the subroutine that it's * * currently within the higher order link structure instead of the main * * structure. It acts like a railroad flow control, diverting the flow * * of the copying in the right direction. * \************************************************************************/ struct fitpars *dup_one_obj (struct fitpars *fpar) { void copy_fitstruct_elem (struct fitpars *to, struct fitpars *from); struct fitpars *new, *fptr; static int high = 0; new = (struct fitpars *) malloc ((size_t) (sizeof (struct fitpars))); if (fpar->outer != NULL) new->outer = (int *) malloc ((size_t) (sizeof (int) * (OFFSET + fpar->outer[0]))); else new->outer = NULL; if (fpar->inner != NULL) new->inner = (int *) malloc ((size_t) (sizeof (int) * (OFFSET + fpar->inner[0]))); else new->inner = NULL; new->a = (float *) malloc ((size_t) (sizeof (float) * (fpar->npars+1))); new->ia = (int *) malloc ((size_t) (sizeof (int) * (fpar->npars+1))); new->sig = (float *) malloc ((size_t) (sizeof (float) * (fpar->npars+1))); new->next = NULL; new->high = NULL; new->dp = NULL; copy_fitstruct_elem (new, fpar); /************************************************************************\ * Recursively go down the higher order deviation linked list. * * * * Note that when high = 1, the truncation reference pointer only comes * * at the end. Truncation reference pointers are linked by * * "link_trunc_fpar" after all the other object structs have been * * linked. * \************************************************************************/ if (fpar->high != NULL) { high += 1; new->high = dup_one_obj (fpar->high); high -= 1; } if (high) { if (fpar->next != NULL) new->next = dup_one_obj (fpar->next); }; return (new); } /****************************************************************************\ * Copy the elements from one structure to the next. * \****************************************************************************/ void copy_fitstruct_elem (struct fitpars *to, struct fitpars *from) { int i; to->compnum = from->compnum; strcpy (to->objtype, from->objtype); to->normtype = from->normtype; if (from->outer != NULL) { for (i=0; i <= from->outer[0]; i++) to->outer[i] = from->outer[i]; }; if (from->inner != NULL) { for (i=0; i <= from->inner[0]; i++) to->inner[i] = from->inner[i]; }; for (i=0; i <= from->npars; i++) { to->a[i] = from->a[i]; to->sig[i] = from->sig[i]; to->ia[i] = from->ia[i]; }; to->npars = from->npars; to->outtype = from->outtype; to->tr_num = from->tr_num; };