/[ascend]/trunk/base/generic/solver/slv_common.h
ViewVC logotype

Diff of /trunk/base/generic/solver/slv_common.h

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 60 by jds, Tue Aug 2 11:20:09 2005 UTC revision 61 by jds, Mon Nov 14 02:37:20 2005 UTC
# Line 29  Line 29 
29   *  COPYING.  COPYING is found in ../compiler.   *  COPYING.  COPYING is found in ../compiler.
30   */   */
31    
32  /** @file  /*
  *  SLV Utilities & Structures for ASCEND Solvers  
  *  <pre>  
33   *  Contents:     slv common utilities and definitions   *  Contents:     slv common utilities and definitions
34   *   *
35   *  Authors:      Ben Allan   *  Authors:      Ben Allan
# Line 40  Line 38 
38   *  Dates:        01/94 - original version   *  Dates:        01/94 - original version
39   *   *
40   *  Description:   *  Description:
41     *
42   *  General C  utility routines for slv/Slv class interfaces. Abstracted from   *  General C  utility routines for slv/Slv class interfaces. Abstracted from
43   *  slvX.c January 1995. Ben Allan.   *  slvX.c January 1995. Ben Allan.
44   *  slv.h is the header for folks on the ASCEND end, and this is the one for   *  slv.h is the header for folks on the ASCEND end, and this is the one for
45   *  folks on the Slv math end.   *  folks on the Slv math end.
46   *  Don't protoize this file for ASCEND types other than mtx, vec, and boolean   *  Don't protoize this file for ASCEND types other than mtx, vec, and boolean
47   *  real64, and int32.   *  real64, and int32 or we'll have you shot. In particular, not var and rel.
48   *  or we'll have you shot. In particular, not var and rel. People   *  People who aren't supposed to know about var and rel include this.
  *  who aren't supposed to know about var and rel include this.  
49   *   *
50   *  In particular, this header may be used without knowing about the ASCEND   *  In particular, this header may be used without knowing about the ASCEND
51   *  compiler or any of its annoying insanities so long as you drag out   *  compiler or any of its annoying insanities so long as you drag out
52   *  ascmalloc.   *  ascmalloc().
53   *  This does commit you to being able to stomach the mtx.h file, however,   *  This does commit you to being able to stomach the mtx.h file, however,
54   *  even if you choose to ignore the contents of mtx.   *  even if you choose to ignore the contents of mtx.
55   *  Several functions, notably the print suite for rel/var names,   *  Several functions, notably the print suite for rel/var names,
# Line 60  Line 58 
58   *   *
59   *  The parameters and status struct definitions have been moved here,   *  The parameters and status struct definitions have been moved here,
60   *  being of general interest.   *  being of general interest.
61   *   */
62    
63    /** @file
64     *  SLV common utilities & structures for ASCEND solvers.
65     *  This includes the following:
66     *    - parameters struct definitions & manipulation routines
67     *    - status struct definitions & retrieval routines
68     *    - vector operations
69     *    - solver print routines
70     *    - lnkmap support functions
71     *  <pre>
72   *  Requires:     #include <stdio.h>   *  Requires:     #include <stdio.h>
73   *                #include "utilities/ascConfig.h"   *                #include "utilities/ascConfig.h"
74     *                #include "solver/slv_types.h"
75     *                #include "solver/rel.h"
76     *                #include "solver/logrel.h"
77     *                #include "solver/mtx.h"
78     *                #include "general/list.h"
79   *  </pre>   *  </pre>
80     *  Details on solver parameter definition:
81     *
82     *  When used together the parameter-related structures, functions, and
83     *  macros allow us to define all of a solver's parameters in one file
84     *  and notify the interface of these parameters upon startup (dynamic
85     *  interface construction).  The parameters can be defined in any order.
86     *  The only bookkeeping needed is associated with the macros.  You must
87     *  have an array of void pointers large enough for all of the macros
88     *  you define and you must give each of the macros you define a unique
89     *  element of this array. Here is an example using a real parameter
90     *  and a character parameter. (The int and bool are similar to the real).
91     *
92     *  ---------- START EXAMPLE CODE ----------
93     *
94     *  (* these 4 macros can be defined anywhere more or less so long as it
95     *  is before the calls to slv_define_parm. *)
96     *  #define REAL_PTR (sys->parm_array[0])
97     *  #define REAL     ((*(real64 *)REAL_PTR))
98     *  #define CHAR_PTR (sys->parm_array[1])
99     *  #define CHAR     ((*(char **)CHAR_PTR))
100     *
101     *  #define PA_SIZE 2
102     *  struct example {
103     *    struct slv_parameters_t p;
104     *    void *parm_array[PA_SIZE];
105     *    struct slv_parameter padata[PA_SIZE];
106     *  } e;
107     *   ...
108     *    e.p.parms = padata;
109     *    e.p.dynamic_parms = 0;
110     *
111     *  static char *character_names[] = {
112     *     "name_one","name_two"
113     *  }
114     *    (* fill padata with appropriate info *)
115     *  slv_define_parm(&(e.p), real_parm,
116     *                  "r_parm","real parameter" ,
117     *                  "this is an example of a real parameter" ,
118     *                  U_p_real(val,25),U_p_real(lo,0),U_p_real(hi,100),1);
119     *   (* now assign the element of e.parm_array from somewhere in padata *)
120     *  SLV_RPARM_MACRO(REAL_PTR,parameters);
121     *
122     *    (* fill padata with appropriate info *)
123     *  slv_define_parm(&(e.p), char_parm,
124     *                  "c_parm", "character parameter",
125     *                  "this is an example of a character parameter",
126     *                  U_p_string(val,character_names[0]),
127     *                  U_p_strings(lo,character_names),
128     *                  U_p_int(hi,sizeof(character_names)/sizeof(char *)),1);
129     *   (* now assign the element of e.parm_array that matches. *)
130     *  SLV_CPARM_MACRO(CHAR_PTR,parameters);
131     *
132     *  Resetting the value of a parameter can be done directly
133     *  except for string parameters which should be set with, for example,
134     *  slv_set_char_parameter(CHAR_PTR,newvalue);
135     *  or outside a solver where there is no sys->parm_array:
136     *
137     *     slv_set_char_parameter(&(p.parms[i].info.c.value),argv[j]);
138     *
139     *  ---------- END OF EXAMPLE CODE ----------
140   */   */
141    
142  #ifndef slv_common__already_included  #ifndef slv_common__already_included
# Line 73  Line 146 
146  #define SLV_INSTANCES TRUE  #define SLV_INSTANCES TRUE
147  /**< SLV_INSTANCES should only be FALSE in a libasc.a free environment */  /**< SLV_INSTANCES should only be FALSE in a libasc.a free environment */
148    
149  /**  /*
150   * Common data structures for Westerberg derived solvers.   * -------------------------------------------------------
151   */   *  Common data structures for Westerberg derived solvers
152     * -------------------------------------------------------
153     */                                          
154    
155    /** Solver output file informationn. */
156  struct slv_output_data {  struct slv_output_data {
157     FILE *more_important;  /**< NULL ==> no output */     FILE *more_important;  /**< More significant output to this file stream.  NULL ==> no output. */
158     FILE *less_important;  /**< NULL ==> no output */     FILE *less_important;  /**< Less significant output to this file stream.  NULL ==> no output. */
159  };  };
160    
161  /**  @todo KHACK THIS SHOULD BE REMOVED */  /**  
162     *  Solver tolerance data structure.
163     *  @todo KHACK THIS SHOULD BE REMOVED - solver/slv_common:slv_tolerance_data.
164     */
165  struct slv_tolerance_data {  struct slv_tolerance_data {
166     real64 drop;         /**< matrix entry drop tolerance during factorization */     real64 drop;         /**< Matrix entry drop tolerance during factorization */
167     real64 pivot;        /**< detect pivot too small, of those available */     real64 pivot;        /**< Detect pivot too small, of those available. */
168     real64 singular;     /**< detect matrix numerically singular */     real64 singular;     /**< Detect matrix numerically singular. */
169     real64 feasible;     /**< detect equality relations satisfied */     real64 feasible;     /**< Detect equality relations satisfied. */
170     real64 rootfind;     /**< detect single equality relation satisfied */     real64 rootfind;     /**< Detect single equality relation satisfied. */
171     real64 stationary;   /**< detect lagrange stationary */     real64 stationary;   /**< Detect lagrange stationary. */
172     real64 termination;  /**< detect progress diminished */     real64 termination;  /**< Detect progress diminished. */
173  };  };
174    
175  /** Solver parameter information. */  /** Solver sub-parameter data structure. */
176  struct slv_sub_parameters {  struct slv_sub_parameters {
177     /* arrays of parametric data */     /* arrays of parametric data */
178     int32   *iap;    /**< Array of parametric int32 data. */     int32   *iap;      /**< Array of parametric int32 data. */
179     real64  *rap;    /**< Array of parametric real64 data. */     real64  *rap;      /**< Array of parametric real64 data. */
180     char*   *cap;    /**< Array of parametric char* data. */     char*   *cap;      /**< Array of parametric char* data. */
181     void*   *vap;    /**< Array of parametric void* data. */     void*   *vap;      /**< Array of parametric void* data. */
182     /* symbolic parameter names */     /* symbolic parameter names */
183     char* *ianames;  /**< Symbolic names for iap parameters. */     char* *ianames;    /**< Array of symbolic names for iap parameters. */
184     char* *ranames;  /**< Symbolic names for rap parameters. */     char* *ranames;    /**< Array of symbolic names for rap parameters. */
185     char* *canames;  /**< Symbolic names for cap parameters. */     char* *canames;    /**< Array of symbolic names for cap parameters. */
186     char* *vanames;  /**< Symbolic names for vap parameters. */     char* *vanames;    /**< Array of symbolic names for vap parameters. */
187     /* longer explanations of the parameter data */     /* longer explanations of the parameter data */
188     char* *iaexpln;  /**< Longer description of iap parameters. */     char* *iaexpln;    /**< Array of longer descriptions of iap parameters. */
189     char* *raexpln;  /**< Longer description of rap parameters. */     char* *raexpln;    /**< Array of longer descriptions of rap parameters. */
190     char* *caexpln;  /**< Longer description of cap parameters. */     char* *caexpln;    /**< Array of longer descriptions of cap parameters. */
191     char* *vaexpln;  /**< Longer description of vap parameters. */     char* *vaexpln;    /**< Array of longer descriptions of vap parameters. */
192     /* lengths of arrays above */     /* lengths of arrays above */
193     int32 ilen;      /**< Length of iap, ianames, and iaexpln. */     int32 ilen;        /**< Length of iap, ianames, and iaexpln arrays. */
194     int32 rlen;      /**< Length of rap, ranames, and raexpln. */     int32 rlen;        /**< Length of rap, ranames, and raexpln arrays. */
195     int32 clen;      /**< Length of cap, canames, and caexpln. */     int32 clen;        /**< Length of cap, canames, and caexpln arrays. */
196     int32 vlen;      /**< Length of vap, vanames, and vaexpln. */     int32 vlen;        /**< Length of vap, vanames, and vaexpln arrays. */
197  };  };
198    
199    /**
200     *  Data structure for solver statistics.
201     *  This is to collect data for the comparison of algorithms.  All solvers
202     *  should have at least one of these, though the interface will check for
203     *  NULL before reading the data.  The interpretation of these data is
204     *  somewhat up to the coder.
205     */
206  struct slv_block_cost {  struct slv_block_cost {
207    int32 size,    int32 size,             /**< How big is the block, in terms of variables? */
208          iterations,          iterations,       /**< How many iterations to convergence/divergence? */
209          funcs,          funcs,            /**< How many function evaluations were made? */
210          jacs,          jacs,             /**< How many jacobian evaluations were made? */
211          reorder_method;          reorder_method;   /**< Not documented. Up to individual solver? */
212    double time,    double time,            /**< How much cpu total time elapsed while in the block? */
213           resid,           resid,           /**< Not documented.  The size of the residual? */
214           functime,           functime,        /**< Time spent in function evaluations. */
215           jactime;           jactime;         /**< Time spent in jacobian evaluations, stuffing. */
216  };  };
217    
218  /** Integer parameter substructure. */  /** Integer solver parameter substructure. */
219  struct slv_int_parameter {  struct slv_int_parameter {
220    int32 value;    int32 value;            /**< Value. */
221    int32 low;    int32 low;              /**< Lower bound. */
222    int32 high;    int32 high;             /**< Upper bound. */
223  };  };
224    
225  /** Boolean parameter substructure. */  /** Boolean solver parameter substructure. */
226  struct slv_boolean_parameter {  struct slv_boolean_parameter {
227    int32 value;    int32 value;            /**< Value. */
228    int32 low;    int32 low;              /**< Lower bound. */
229    int32 high;    int32 high;             /**< Upper bound. */
230  };  };
231    
232  /** Real parameter substructure. */  /** Real solver parameter substructure. */
233  struct slv_real_parameter {  struct slv_real_parameter {
234    double value;    double value;           /**< Value. */
235    double low;    double low;             /**< Lower bound. */
236    double high;    double high;            /**< Upper bound. */
237  };  };
238    
239  /** Char parameter substructure. */  /** Char solver parameter substructure. */
240  struct slv_char_parameter {  struct slv_char_parameter {
241    char *value;    char *value;            /**< Value. */
242    char **argv;    char **argv;            /**< Lower bound. */
243    int32 high;    int32 high;             /**< Upper bound. */
244  };  };
245    
246  /** Basic solver parameter types. */  /** Basic solver parameter types. */
247  enum parm_type {  enum parm_type {
248    int_parm,    int_parm,                 /**< Integer type. */
249    bool_parm,    bool_parm,                /**< Boolean type. */
250    real_parm,    real_parm,                /**< Real type. */
251    char_parm    char_parm                 /**< Char type. */
252  };  };
253    
254    /** Parameter arguments */
255  union parm_arg  union parm_arg
256  {  {
257    char **argv;    char **argv;              /**< Strings array argument. */
258    char *argc;   /**< huh? */    char *argc;               /**< Char argument. */
259    int32 argi;    int32 argi;               /**< Integer argument. */
260    int32 argb;    int32 argb;               /**< Boolean argument. */
261    real64 argr;    real64 argr;              /**< Real argument. */
262  };  };
263    
264  /**  /** Solver parameter structure. */
  *  Solver parameter structure.  
  *  @todo Shouldn't b be a slv_boolean_parameter?  
  */  
265  struct slv_parameter {  struct slv_parameter {
266    enum parm_type type;    /**< parameter type */    enum parm_type type;              /**< Parameter type. */
267    int32 number;           /**< index in array */    int32 number;                     /**< Index in array. */
268    int32 display;          /**< display page */    int32 display;                    /**< Display page. */
269    char *name;             /**< scripting short name */    char *name;                       /**< Scripting short name. */
270    char *interface_label;  /**< user interface label */    char *interface_label;            /**< User interface label. */
271    char *description;      /**< modest help string */    char *description;                /**< Modest help string. */
272    union {    union {
273      struct slv_int_parameter i;      struct slv_int_parameter i;     /**< Integer parameter. */
274      struct slv_int_parameter b;      struct slv_boolean_parameter b; /**< Boolean parameter. */
275      struct slv_real_parameter r;      struct slv_real_parameter r;    /**< Real parameter. */
276      struct slv_char_parameter c;      struct slv_char_parameter c;    /**< Char parameter. */
277    } info;                 /**< data */    } info;                           /**< Data. */
278  };  };
279    
280  /*  /*
# Line 203  struct slv_parameter { Line 288  struct slv_parameter {
288    
289  #define U_p_int(parm_u,val)     ((((parm_u).argi = (val))), (parm_u))  #define U_p_int(parm_u,val)     ((((parm_u).argi = (val))), (parm_u))
290  /**<  /**<
291   *  Sets the argi of the parm_arg parm_u to val and returns parm_u.   *  Sets the argi of parm_arg parm_u to val and returns the parm_u.
292   *  For use in calls to slv_define_parm().   *  This macro is used for setting integer parm_arg arguments in calls
293     *  to slv_define_parm().  parm_u should be one of { val, lo, hi },
294     *  which correspond to local parm_arg variables that should be used
295     *  in client functions calling slv_define_parm().
296     *
297     *  @param parm_u The parm_arg to modify, one of {val, lo, hi}.
298     *  @param val    int, the new value for the parm_arg.
299     *  @return Returns parm_u.
300   */   */
301  #define U_p_bool(parm_u,val)    ((((parm_u).argb = (val))), (parm_u))  #define U_p_bool(parm_u,val)    ((((parm_u).argb = (val))), (parm_u))
302  /**<  /**<
303   *  Sets the argb of the parm_arg parm_u to val and returns parm_u.   *  Sets the argb of parm_arg parm_u to val and returns the parm_u.
304   *  For use in calls to slv_define_parm().   *  This macro is used for setting boolean parm_arg arguments in calls
305     *  to slv_define_parm().  parm_u should be one of { val, lo, hi },
306     *  which correspond to local parm_arg variables that should be used
307     *  in client functions calling slv_define_parm().
308     *
309     *  @param parm_u The parm_arg to modify, one of {val, lo, hi}.
310     *  @param val    boolean, the new value for the parm_arg.
311     *  @return Returns parm_u.
312   */   */
313  #define U_p_real(parm_u,val)    ((((parm_u).argr = (val))), (parm_u))  #define U_p_real(parm_u,val)    ((((parm_u).argr = (val))), (parm_u))
314  /**<  /**<
315   *  Sets the argr of the parm_arg parm_u to val and returns parm_u.   *  Sets the argr of parm_arg parm_u to val and returns the parm_u.
316   *  For use in calls to slv_define_parm().   *  This macro is used for setting real parm_arg arguments in calls
317     *  to slv_define_parm().  parm_u should be one of { val, lo, hi },
318     *  which correspond to local parm_arg variables that should be used
319     *  in client functions calling slv_define_parm().
320     *
321     *  @param parm_u The parm_arg to modify, one of {val, lo, hi}.
322     *  @param val    double, the new value for the parm_arg.
323     *  @return Returns parm_u.
324   */   */
325  #define U_p_string(parm_u,val)  ((((parm_u).argc = (val))), (parm_u))  #define U_p_string(parm_u,val)  ((((parm_u).argc = (val))), (parm_u))
326  /**<  /**<
327   *  Sets the argc of the parm_arg parm_u to val and returns parm_u.   *  Sets the argc of parm_arg parm_u to val and returns the parm_u.
328     *  This macro is used for setting string parm_arg arguments in calls
329     *  to slv_define_parm().  parm_u should be one of { val, lo, hi },
330     *  which correspond to local parm_arg variables that should be used
331     *  in client functions calling slv_define_parm().
332     *
333     *  @param parm_u The parm_arg to modify, one of {val, lo, hi}.
334     *  @param val    char *, the new value for the parm_arg.
335     *  @return Returns parm_u.
336   *  For use in calls to slv_define_parm().   *  For use in calls to slv_define_parm().
337   */   */
338  #define U_p_strings(parm_u,val) ((((parm_u).argv = (val))), (parm_u))  #define U_p_strings(parm_u,val) ((((parm_u).argv = (val))), (parm_u))
339  /**<  /**<
340   *  Sets the argv of the parm_arg parm_u to val and returns parm_u.   *  Sets the argv of parm_arg parm_u to val and returns the parm_u.
341     *  This macro is used for setting string array parm_arg arguments in
342     *  calls to slv_define_parm().  parm_u should be one of { val, lo, hi },
343     *  which correspond to local parm_arg variables that should be used
344     *  in client functions calling slv_define_parm().
345     *
346     *  @param parm_u The parm_arg to modify, one of {val, lo, hi}.
347     *  @param val    char **, the new value for the parm_arg.
348     *  @return Returns parm_u.
349   *  For use in calls to slv_define_parm().   *  For use in calls to slv_define_parm().
350   */   */
351    
352  #define SLV_IPARM_MACRO(X,P) \  #define SLV_IPARM_MACRO(NAME,slv_parms) \
353    if (make_macros == 1) {  \    if (make_macros == 1) {  \
354       (X)  = &((P)->parms[(P)->num_parms-1].info.i.value); \       (NAME)  = &((slv_parms)->parms[(slv_parms)->num_parms-1].info.i.value); \
355    }    }
356  /**<  /**<
357   *  Macro for defining macros of type integer (IPARM).   *  Macro for defining macros of type integer (IPARM).
358   *  See SLV_CPARM_MACRO() for more information.   *  See SLV_CPARM_MACRO() for more information.
359   */   */
360  #define SLV_BPARM_MACRO(X,P) \  #define SLV_BPARM_MACRO(NAME,slv_parms) \
361    if (make_macros == 1) {  \    if (make_macros == 1) {  \
362       (X)  = &((P)->parms[(P)->num_parms-1].info.b.value); \       (NAME)  = &((slv_parms)->parms[(slv_parms)->num_parms-1].info.b.value); \
363    }    }
364  /**<  /**<
365   *  Macro for defining macros of type boolean (BPARM).   *  Macro for defining macros of type boolean (BPARM).
366   *  See SLV_CPARM_MACRO() for more information.   *  See SLV_CPARM_MACRO() for more information.
367   */   */
368  #define SLV_RPARM_MACRO(X,P) \  #define SLV_RPARM_MACRO(NAME,slv_parms) \
369    if (make_macros == 1) {  \    if (make_macros == 1) {  \
370       (X)  = &((P)->parms[(P)->num_parms-1].info.r.value); \       (NAME)  = &((slv_parms)->parms[(slv_parms)->num_parms-1].info.r.value); \
371    }    }
372  /**<  /**<
373   *  Macro for defining macros of type real (RPARM).   *  Macro for defining macros of type real (RPARM).
374   *  See SLV_CPARM_MACRO() for more information.   *  See SLV_CPARM_MACRO() for more information.
375   */   */
376  #define SLV_CPARM_MACRO(X,P) \  #define SLV_CPARM_MACRO(NAME,slv_parms) \
377    if (make_macros == 1) {  \    if (make_macros == 1) {  \
378       (X)  = &((P)->parms[(P)->num_parms-1].info.c.value); \       (NAME)  = &((slv_parms)->parms[(slv_parms)->num_parms-1].info.c.value); \
379    }    }
380  /**<  /**<
381   * Macro for defining macros of type character (CPARM).   * Macro for defining macros of type character (CPARM).
382   * To use, send in a name (X) for the macro (in caps by convention)   * To use, provide a NAME for the macro (in caps by convention)
383   * and a slv_parameters_t pointer (P). The name (X) should be   * and a slv_parameters_t pointer (slv_parm). The NAME should be
384   * defined as an element in an array of void pointers in the   * defined as an element in an array of void pointers in the
385   * module in which the macro is to be used.  This macro uses the   * module in which the macro is to be used.  This macro uses the
386   * current number of registered parameters to link the array of   * current number of registered parameters to link the array of
# Line 393  struct slv_parameter { Line 515  struct slv_parameter {
515   *  </pre>   *  </pre>
516   */   */
517  typedef struct slv_parameters_structure {  typedef struct slv_parameters_structure {
518     struct slv_output_data output;     struct slv_output_data output;       /**< File streams for solver output. */
519     struct slv_tolerance_data tolerance;     struct slv_tolerance_data tolerance; /**< Defince various tolerances for the solver. */
520     struct slv_parameter *parms;     struct slv_parameter *parms;         /**< Holds the parameters defined for a solver. */
521     int32 num_parms;     int32 num_parms;                     /**< The number of parameters in parms. */
522     int32 dynamic_parms;     /**< set 1 if parms is dynamically allocated */     int32 dynamic_parms;                 /**< Set to TRUE if parms is dynamically allocated. */
523    
524     /* we wish the following were on the way out */     /* we wish the following were on the way out */
525     struct slv_sub_parameters sp;     struct slv_sub_parameters sp;        /**< Solver sub-parameters. */
526     int whose;     int whose;                           /**< Code for where a parameter set came from. */
527     int32 ignore_bounds;     int32 ignore_bounds;                 /**< Set to TRUE to disregard boundary conditions. */
528     int32 partition;     int32 partition;                     /**< Set to TRUE if system will be partitioned into blocks. */
529    
530     /* the following are on the way out */     /* the following are on the way out */
531     double time_limit;     /**< @todo kill */     double time_limit;     /**< Max cpu seconds per block.                   @todo kill */
532     double rho;            /**< @todo kill */     double rho;            /**< Scaler premultiplier of penalty term.        @todo kill */
533     int32 iteration_limit; /**< @todo kill */     int32 iteration_limit; /**< Max number of iterations.                    @todo kill */
534     int32 factor_option;   /**< @todo kill */     int32 factor_option;   /**< Suggests a number for linear factorization.  @todo kill */
535    
536  } slv_parameters_t;  } slv_parameters_t;
537    
 /**  
  *  Deallocates any memory allocated durring parameter creation.  
  *  if !(p->dynamic_parms), frees strings in p->parms but not p->parms.  
  */  
 extern void slv_destroy_parms(slv_parameters_t *p);  
538    
539  /**  /* slv_destroy_parms() is defined in slv.c */
540   * <!--  slv_define_parm: Function for adding (defining) a new         -->  extern void slv_destroy_parms(slv_parameters_t *p);
541   * <!--  parameter in your parameter structure.                        -->  /**<
542   * <!--  err = slv_define_parm(p,type,interface_name,                  -->   *  Deallocates any allocated memory held by a parameter structure.
543   * <!--                        interface_label,description,            -->   *  Only the held memory is freed, not p itself.  Further, if
544   * <!--                        value, lower_bound,upper_bound,         -->   *  (p->dynamic_parms != 0), the strings in p->parms are freed
545   * <!--                        page);                                  -->   *  but not p->parms itself.  Does nothing if p is NULL.
546   *   *
547   * <!--  int32 err                                                     -->   *  @param p  The parameter structure to destroy.
  * <!--  slv_parameters_t *p                                           -->  
  * <!--  enum parm_type type                                           -->  
  * <!--  char *interface_name                                          -->  
  * <!--  char *interface_label                                         -->  
  * <!--  char *description                                             -->  
  * <!--  union parm_arg value                                          -->  
  * <!--  union parm_arg lower_bound                                    -->  
  * <!--  union parm_arg upper_bound                                    -->  
  * <!--  int32 page                                                    -->  
  *  
  *  Adds (defines) a new parameter in the parameter structure.  
  *  Returns err = -1 if p is NULL or called with unsupported type.  
  *  Returns err = number of registered parameters otherwise.  
  *  Supported types are int_parm, bool_parm,real_parm, and char_parm.  
  *  interface name should be a very short but descriptive name that  
  *  the interface can use to identify the parameter. The interface label  
  *  should be a short text string to be displayed on the interface.  
  *  The description should be a slightly more detailed string to be  
  *  displayed upon request a la balloon help.  
  *  The value, lower_bound, and upper_bound fields should be filled  
  *  using the appropriate parm_arg union macros defined above.  
  *  page should indicate the parameter page number that the parameter  
  *  is to be displayed on.  By convention page is set to -1 for parameters  
  *  which are not to be displayed on the interface.  
548   */   */
549    
550    /* slv_define_parm() is defined in slv.c */
551  extern int32 slv_define_parm(slv_parameters_t *p,  extern int32 slv_define_parm(slv_parameters_t *p,
552                               enum parm_type type,                               enum parm_type type,
553                               char *interface_name,                               char *interface_name,
# Line 462  extern int32 slv_define_parm(slv_paramet Line 557  extern int32 slv_define_parm(slv_paramet
557                               union parm_arg lower_bound,                               union parm_arg lower_bound,
558                               union parm_arg upper_bound,                               union parm_arg upper_bound,
559                               int32 page);                               int32 page);
560    /**<
561  /** <!--  PARM VALUES                                                  -->   *  Adds (defines) a new parameter in a parameter structure.
562   * Resetting the value of a parameter can be done directly   *  Use this function to add & define new parameters for a solver.
563   * except for string parameters which must be set with   *
564   * slv_set_char_parameter(stringpointer,charvalue);   *  @param p                Parameter structure to receive the new parameter.
565   * slv_set_char_parameter does not keep the charvalue string you pass it.   *  @param type             Parameter type: int_parm, bool_parm, real_parm, or char_parm.
566     *  @param interface_name   A very short but descriptive name that the interface
567     *                          can use to identify the parameter.
568     *  @param interface_label  A short text string to be displayed on the interface.
569     *  @param description      A slightly more detailed string to be displayed
570     *                          upon request a la balloon help.
571     *  @param value            The value for the parameter, set using one of
572     *                          the U_p_int() style macros defined above.
573     *  @param lower_bound      The lower bound for the parameter, set using one of
574     *                          the U_p_int() style macros defined above.
575     *  @param upper_bound      The upper bound for the parameter, set using one of
576     *                          the U_p_int() style macros defined above.
577     *  @param page             The page of the interface options dialog on which
578     *                          to display this parameter.  Ranges from 1..max_page_no.
579     *                          Set to -1 if this parameter is not to be displayed in
580     *                          the interface.
581     *  @return Returns -1 if p is NULL or called with unsupported type;
582     *          otherwise returns the number of registered parameters in p.
583   */   */
 extern void slv_set_char_parameter(char **cptr, char *newvalue);  
584    
585  /*  /* slv_set_char_parameter() is defined in slv.c */
586   * When used together the above structures, functions, and macros  extern void slv_set_char_parameter(char **cptr, char *newvalue);
587   * allow us to define all of a solver's parameters in one file and  /**<
588   * notify the interface of these parameters upon startup (dynamic   *  Sets a char parameter value to a new string.
589   * interface construction).  The parameters can be defined in any order.   *  Resetting the value of a parameter can be done directly except
590   * The only bookkeeping needed is associated with the macros.  You must   *  for string parameters which must be set with this function.  The
591   * have an array of void pointers large enough for all of the macros   *  string newvalue is not kept by the function.<br><br>
592   * you define and you must give each of the macros you define a unique   *
593   * element of this array. Here is an example using a real parameter   *  Example:   slv_set_char_parameter(&(p.parms[i].info.c.value),argv[j]);
  * and a character parameter. (The int and bool are similar to the real).  
  *  
  * ---------- START EXAMPLE CODE ----------  
  *  
  * (* these 4 macros can be defined anywhere more or less so long as it  
  * is before the calls to slv_define_parm. *)  
  * #define REAL_PTR (sys->parm_array[0])  
  * #define REAL     ((*(real64 *)REAL_PTR))  
  * #define CHAR_PTR (sys->parm_array[1])  
  * #define CHAR     ((*(char **)CHAR_PTR))  
  *  
  * #define PA_SIZE 2  
  * struct example {  
  *   struct slv_parameters_t p;  
  *   void *parm_array[PA_SIZE];  
  *   struct slv_parameter padata[PA_SIZE];  
  * } e;  
  *  ...  
  *   e.p.parms = padata;  
  *   e.p.dynamic_parms = 0;  
  *  
  * static char *character_names[] = {  
  *    "name_one","name_two"  
  * }  
  *   (* fill padata with appropriate info *)  
  * slv_define_parm(&(e.p), real_parm,  
  *                 "r_parm","real parameter" ,  
  *                 "this is an example of a real parameter" ,  
  *                 U_p_real(val,25),U_p_real(lo,0),U_p_real(hi,100),1);  
  *  (* now assign the element of e.parm_array from somewhere in padata *)  
  * SLV_RPARM_MACRO(REAL_PTR,parameters);  
  *  
  *   (* fill padata with appropriate info *)  
  * slv_define_parm(&(e.p), char_parm,  
  *                 "c_parm", "character parameter",  
  *                 "this is an example of a character parameter",  
  *                 U_p_string(val,character_names[0]),  
  *                 U_p_strings(lo,character_names),  
  *                 U_p_int(hi,sizeof(character_names)/sizeof(char *)),1);  
  *  (* now assign the element of e.parm_array that matches. *)  
  * SLV_CPARM_MACRO(CHAR_PTR,parameters);  
  *  
  * Resetting the value of a parameter can be done directly  
  * except for string parameters which should be set with, for example,  
  * slv_set_char_parameter(CHAR_PTR,newvalue);  
  * or outside a solver where there is no sys->parm_array:  
  *   slv_set_char_parameter(&(p.parms[i].info.c.value),argv[j]);  
594   *   *
595   * ---------- END OF EXAMPLE CODE ----------   *  @param cptr     Pointer to the char array to set.
596     *  @param newvalue New value for *cptr.
597   */   */
598    
599    /** Solver block status record. */
600  struct slv__block_status_structure {  struct slv__block_status_structure {
601     int32 number_of;     int32 number_of;                 /**< Number of blocks in system. */
602     int32 current_block;     int32 current_block;             /**< Block number of the current block that the
603     int32 current_reordered_block;                                           solver is working on.  It is assumed that all
604     int32 current_size;                                           previous blocks have already converged. */
605     int32 previous_total_size;     int32 current_reordered_block;   /**< Number of the block most recently reordered. */
606     int32 previous_total_size_vars;     int32 current_size;              /**< Number of variables/relations in the current block. */
607     int32 iteration;     int32 previous_total_size;       /**< Total size of previous blocks (= number of
608     int32 funcs;                                           variables/relations already converged). */
609     int32 jacs;     int32 previous_total_size_vars;  /**< Not currently implemented. */
610     double cpu_elapsed;     int32 iteration;                 /**< Number of iterations so far in the current block. */
611     double functime;     int32 funcs;                     /**< Number of residuals calculated in the current block. */
612     double jactime;     int32 jacs;                      /**< Number of jacobians evaluated in the current block. */
613     real64 residual;     double cpu_elapsed;              /**< Number of cpu seconds elapsed in the current block. */
614       double functime;                 /**< Number of cpu seconds elapsed getting residuals. */
615       double jactime;                  /**< Number of cpu seconds elapsed getting jacobians. */
616       real64 residual;                 /**< Current residual (RMS value) for the current block. */
617  };  };
618    
619  /**  /**
# Line 662  struct slv__block_status_structure { Line 731  struct slv__block_status_structure {
731   *  </pre>   *  </pre>
732   */   */
733  typedef struct slv_status_structure {  typedef struct slv_status_structure {
734     uint32 ok : 1;     uint32 ok : 1;                       /**< If TRUE, everything is ok. */
735     uint32 over_defined : 1;     uint32 over_defined : 1;             /**< Is system over-defined? */
736     uint32 under_defined : 1;     uint32 under_defined : 1;            /**< Is system under-defined? */
737     uint32 struct_singular : 1;     uint32 struct_singular : 1;          /**< Is system structurally singular? */
738     uint32 ready_to_solve : 1;     uint32 ready_to_solve : 1;           /**< Is system ready to solve? */
739     uint32 converged : 1;     uint32 converged : 1;                /**< Has system fully convergeded? */
740     uint32 diverged : 1;     uint32 diverged : 1;                 /**< Has system diverged? */
741     uint32 inconsistent : 1;     uint32 inconsistent : 1;             /**< Was system was found to be inconsistent? */
742     uint32 calc_ok : 1;     uint32 calc_ok : 1;                  /**< Were any errors encounted calculating residuals? */
743     uint32 iteration_limit_exceeded : 1;     uint32 iteration_limit_exceeded : 1; /**< Was the iteraction limit exceeded? */
744     uint32 time_limit_exceeded : 1;     uint32 time_limit_exceeded : 1;      /**< Was the time limit exceeded? */
745     uint32 panic :1;     uint32 panic :1;                     /**< Did the user stop the solver interactively? */
746     int32 iteration;     int32 iteration;                     /**< Total number of iterations so far. */
747     int32 costsize;     int32 costsize;                      /**< Number of elements in the cost array. */
748     double cpu_elapsed;     double cpu_elapsed;                  /**< Total elapsed cpu seconds. */
749     struct slv_block_cost *cost;     struct slv_block_cost *cost;         /**< Array of slv_block_cost records. */
750     struct slv__block_status_structure block;     struct slv__block_status_structure block;  /**< Block status information. */
751  } slv_status_t;  } slv_status_t;
752    
753  /**  A dense vector class of some utility and the functions for it. */  /*
754     * --------------------------------
755     *  vector_data class & operations
756     * --------------------------------
757     *
758     *  If we get brave, we will consider replacing the cores of these
759     *  routines with blas calls. We aren't overeager to go mixed
760     *  language call nuts just yet, however.
761     */
762    
763    /**  
764     *  A dense vector class of some utility and the functions for it.
765     *  The vector consists of an array of real64 (vec) and a mtx_range_t
766     *  (rng) which refers to subsets of the range of indexes of vec.
767     *  When calling the various vector functions, the range indexes in
768     *  rng are used to calculate offsets in the vec array.  Therefore,
769     *  it is important that your rng->(low,high) refer to valid indexes
770     *  of vec[].  In particular
771     *    - neither rng->low nor rng->high may be negative
772     *    - low <= high
773     *    - high < length of vec
774     *  This means that whatever your maximum high is, you should allocate
775     *  (high+1) values in vec.
776     *  @todo solver/slv_common:vector_data & operations should be
777     *        moved to a module in general or utilities.
778     */
779  struct vector_data {  struct vector_data {
780     real64       norm2;        /**< 2-norm of vector squared */     real64       norm2;      /**< 2-norm of vector squared. */
781     mtx_range_t  *rng;         /**< Pointer to range */     mtx_range_t  *rng;       /**< Pointer to range of vector (low..high). */
782     real64       *vec;         /**< NULL => uninitialized */     real64       *vec;       /**< Data array (NULL => uninitialized). */
783     boolean      accurate;     /**< ? is vector currently accurate */     boolean      accurate;   /**< Is vector currently accurate?  User-manipulated. */
784  };  };
785    
786  /*  extern struct vector_data *slv_create_vector(int32 low, int32 high);
787   *  vector_data operations.  /**<
788     *  Returns a new vector_data initialized to the specified range.
789     *  This function creates, initializes, and returns a new vector_data
790     *  structure.  The vector is initialized using init_vector() and
791     *  a pointer to the new struct is returned.  If the specified range
792     *  is improper (see slv_init_vector()) then a valid vector cannot be
793     *  created and NULL is returned.<br><br>
794     *
795     *  Destruction of the returned vector_data is the responsibility of
796     *  the caller.  slv_destroy_vector() may be used for this purpose.
797     *
798     *  @param low  The lower bound of the vector's range.
799     *  @param high The upper bound of the vector's range.
800     *  @return A new initialized vector_data, or NULL if one could
801     *          not be created.
802     */
803    
804    extern int slv_init_vector(struct vector_data *vec, int32 low, int32 high);
805    /**<
806     *  Initializes a vector_data structure.
807     *  The new range (low..high) is considered proper if both low and
808     *  high are zero or positive, and (low <= high).  If the new range is
809     *  not proper (or if vec itself is NULL), then no modifications are
810     *  made to vec.<br><br>
811     *
812     *  If the range is proper then vec->rng is allocated if NULL and then
813     *  set using low and high.  Then vec->vec is allocated (if NULL) or
814     *  reallocated to size (high+1).  The data in vec->vec is not
815     *  initialized or changed.  The member vec->accurate is set to FALSE.
816     *
817     *  @param vec  Pointer to the vector_data to initialize.
818     *  @param low  The lower bound of the vector's range.
819     *  @param high The upper bound of the vector's range.
820     *  @return Returns 0 if the vector is initialized successfully,
821     *          1 if an improper range was specified, 2 if vec is NULL,
822     *          and 3 if memory cannot be allocated.
823     */
824    
825    extern void slv_destroy_vector(struct vector_data *vec);
826    /**<
827     *  Destroys a vector and its assocated data.
828     *  Deallocates any memory held in vec->rng and vec->vec,
829     *  and then deallocates the vector itself.  NULL is tolerated
830     *  for vec, vec->rng, or vec->vec.
831   *   *
832   *  If we get brave, we will consider replacing the cores of these   *  @param vec Pointer to the vector_data to destroy.
  *  routines with blas calls. We aren't just overeager to go mixed  
  *  language call nuts yet, however.  
833   */   */
834    
835  extern void slv_zero_vector(struct vector_data *vec);  extern void slv_zero_vector(struct vector_data *vec);
836  /**<  /**<
837   *  <!--  slv_zero_vector(struct vector_data *vec);                    -->   *  Zeroes a vector.
838   *  Assign vector entries between vec->rng.low and  vec->rng.high to 0.0.   *  The vector entries between vec->rng.low and  vec->rng.high will
839     *  be set to 0.0.  
840     *  The following are not allowed and are checked by assertion:
841     *    - NULL vec
842     *    - NULL vec->rng
843     *    - NULL vec->vec
844     *    - vec->rng->low < 0
845     *    - vec->rng->low > vec->rng->high
846     *
847     *  @param vec The vector to zero.
848   */   */
849    
850  extern void slv_copy_vector(struct vector_data *vec1,  extern void slv_copy_vector(struct vector_data *srcvec,
851                              struct vector_data *vec2);                              struct vector_data *destvec);
852  /**<  /**<
853   *  <!--  slv_copy_vector(struct vector_data *vec1, struct vector_data *vec2); -->   *  Copies the data from srcvec to destvec.
854   *  Copy data [vec1->rng.low .. vec1->rng.high] to vec2 starting   *  The data in the range [srcvec->rng.low .. srcvec->rng.high]
855   *  at position vec2->rng.low.   *  is copied to destvec starting at position destvec->rng.low.
856     *  destvec must have at least as many elements in vec as srcvec.
857     *  The following are not allowed and are checked by assertion:
858     *    - NULL srcvec
859     *    - NULL srcvec->rng
860     *    - NULL srcvec->vec
861     *    - srcvec->rng->low < 0
862     *    - srcvec->rng->low > srcvec->rng->high
863     *    - NULL destvec
864     *    - NULL destvec->rng
865     *    - NULL destvec->vec
866     *    - destvec->rng->low < 0
867   *   *
868   *  @todo  Copyvector could stand to be optimized.   *  @param srcvec  The vector to copy.
869     *  @param destvec The vector to receive the copied data.
870   */   */
871    
872  extern real64 slv_inner_product(struct vector_data *vec1,  extern real64 slv_inner_product(struct vector_data *vec1,
873                                  struct vector_data *vec2);                                  struct vector_data *vec2);
874  /**<  /**<
875   *  <!--  slv_inner_product(struct vector_data *vec1, struct vector_data *vec2); -->   *  Calculates the dot product of 2 vectors.
876   *  Dot [vec1->rng.low .. vec1->rng.high] with vec2 starting at   *  Dot [vec1->rng.low .. vec1->rng.high] with vec2 starting at
877   *  position vec2->rng.low.   *  position vec2->rng.low.
878   *   *  The following are not allowed and are checked by assertion:
879   *  @todo inner_product could stand to be optimized.   *    - NULL vec1
880     *    - NULL vec1->rng
881     *    - NULL vec1->vec
882     *    - vec1->rng->low < 0
883     *    - vec1->rng->low > vec1->rng->high
884     *    - NULL vec2
885     *    - NULL vec2->rng
886     *    - NULL vec2->vec
887     *    - vec2->rng->low < 0
888     *
889     *  @param vec1 The 1st vector for the dot product.
890     *  @param vec2 The 2nd vector for the dot product.
891     *  @todo solver/slv_common:slv_inner_product() could stand to be optimized.
892   */   */
893    
894  extern real64 slv_square_norm(struct vector_data *vec);  extern real64 slv_square_norm(struct vector_data *vec);
895  /**<  /**<
896   *  <!--  slv_square_norm(struct vector_data *vec);                    -->   *  Calculates the dot product of a vector with itself.
897   *  Dot [vec->rng.low .. vec->rng.high] with itself and store the   *  Dot [vec->rng.low .. vec->rng.high] with itself and store the
898   *  result in vec->norm2.   *  result in vec->norm2.
899     *  The following are not allowed and are checked by assertion:
900     *    - NULL vec
901     *    - NULL vec->rng
902     *    - NULL vec->vec
903     *    - vec->rng->low < 0
904     *    - vec->rng->low > vec->rng->high
905   *   *
906   *  @todo square_norm could stand to be optimized.   *  @param vec The vector for the dot product.
907     *  @todo solver/slv_common:slv_square_norm() could stand to be optimized.
908   */   */
909    
910  extern void slv_matrix_product(mtx_matrix_t mtx,  extern void slv_matrix_product(mtx_matrix_t mtx,
911                                 struct vector_data *vec,                                 struct vector_data *vec,
912                                 struct vector_data *prod,                                 struct vector_data *prod,
913                                 real64 scale,                                 real64 scale,
914                                 boolean transpose);                                 boolean transpose);
915  /**<  /**<
916   *  <!--  slv_matrix_product(mtx,vec,prod,scale,transpose)             -->   *  Calculates the product of a vector, matrix, and scale factor.
917   *  <!--  mtx_matrix_t mtx;                                            -->   *  Stores prod := (scale)*(mtx)*(vec) if transpose = FALSE,
918   *  <!--  struct vector_data *vec,*prod;                               -->   *  or prod := (scale)*(mtx-transpose)(vec) if transpose = TRUE.
  *  <!--  real64 scale;                                                -->  
  *  <!--  boolean transpose;                                           -->  
  *  
  *  Stores prod := (scale)*(mtx)(vec) or (scale)*(mtx-transpose)(vec).  
919   *  vec and prod must be completely different.   *  vec and prod must be completely different.
920   *  If (!transpose) vec->vec is assumed indexed by current col and   *  If (!transpose) vec->vec is assumed indexed by current col and
921   *                 prod->vec is indexed by current row of mtx.   *                 prod->vec is indexed by current row of mtx.
922   *  If (transpose) vec->vec is assumed indexed by current row and   *  If (transpose) vec->vec is assumed indexed by current row and
923   *                 prod->vec is indexed by current col of mtx.   *                 prod->vec is indexed by current col of mtx.
924     *  The following are not allowed and are checked by assertion:
925     *    - NULL mtx
926     *    - NULL vec
927     *    - NULL vec->rng
928     *    - NULL vec->vec
929     *    - vec->rng->low < 0
930     *    - vec->rng->low > vec->rng->high
931     *    - NULL prod
932     *    - NULL prod->rng
933     *    - NULL prod->vec
934     *    - prod->rng->low < 0
935     *    - prod->rng->low > prod->rng->high
936     *
937     *  @param mtx       The matrix for the product.
938     *  @param vec       The vector for the product.
939     *  @param prod      The vector to receive the matrix product.
940     *  @param scale     The scale factor by which to multiply the matrix product.
941     *  @param transpose Flag for whether to use mtx or its transpose.
942   *   *
943   *  @todo mtx_product needs attention - does it go into mtx?   *  @todo solver/slv_common:slv_mtx_product needs attention -
944     *        does it go into mtx?
945   */   */
946    
947  extern void slv_write_vector(FILE *fp, struct vector_data *vec);  extern void slv_write_vector(FILE *fp, struct vector_data *vec);
948  /**<  /**<
949   *  <!--  slv_write_vector(fp,vec)                                     -->   *  Write vector information to a file stream.
950   *  Write the values in the range of the vector to file fp along with   *  Prints general information about the vector followed by the
951   *  a few other doodads.   *  values in the range of the vector to file fp.
952     *
953     *  @param fp  The file stream to receive the report.
954     *  @param vec The vector on which to report.
955   */   */
956    
957  /*  /*
958   * Misc. BLAS-like functions.   * ----------------------------
959     *  Misc. BLAS-like functions
960     * ----------------------------
961   */   */
962    
 /**  
  *  <!--  sum=slv_dot(len, a1, a2);                                    -->  
  *  <!--  real64 *a1, *a2, sum;                                        -->  
  *  <!--  int32 len;                                                   -->  
  *  Dot product of 2 arrays of real64. Loop unrolled.  
  *  Takes advantage of identical vectors.  
  *  
  *  Used inside slv_inner_product, so no need to use specially  
  *  if you are using the vector_data type.  
  */  
963  extern real64 slv_dot(int32 len, const real64 *a1, const real64 *a2);  extern real64 slv_dot(int32 len, const real64 *a1, const real64 *a2);
964    /**<
965     *  Calculates the dot product of 2 arrays of real64.
966     *  This is an optimized routine (loop unrolled).  It takes
967     *  advantage of identical vectors.  The 2 arrays must have
968     *  at least len elements.
969     *  The following are not allowed and are checked by assertion:
970     *    - NULL a1
971     *    - NULL a2
972     *    - len < 0
973     *
974     *  The same algorithm is used inside slv_inner_product(), so there
975     *  is no need to use this function directly if you are using the
976     *  vector_data type.
977     *
978     *  @param len The length of the 2 arrays.
979     *  @param a1  The 1st array for the dot product.
980     *  @param a2  The 2nd array for the dot product.
981     */
982    
983  /*  /*
984     * --------------------------------
985   *  General input/output routines   *  General input/output routines
986   *  -----------------------------   * --------------------------------
987   */   */
988    
989  /**  extern FILE *slv_get_output_file(FILE *fp);
990   *  Takes a file pointer, and if it is null returns a pointer to /dev/null.  /**<
991     *  Checks a file pointer, and if NULL returns a pointer to the nul device.
992   *  If you are in environment that doesn't have something like   *  If you are in environment that doesn't have something like
993   *  /dev/null, you'd better be damn sure your sys->p.output.*_important   *  /dev/null (nul on Windows), you'd better be damn sure your
994   *  is not NULL.   *  sys->p.output.*_important are not NULL.
995     *
996     *  @param fp The file stream to check.
997     *  @return fp if it is not NULL, a pointer to the nul device otherwise.
998   */   */
 extern FILE *slv_get_output_file(FILE *fp);  
999    
1000  /*  /*
1001   * FILE pointer macros.   * FILE pointer macros.
# Line 798  extern FILE *slv_get_output_file(FILE *f Line 1005  extern FILE *slv_get_output_file(FILE *f
1005   *     fp = PLIF(sys)   *     fp = PLIF(sys)
1006   *     or fprintf(MIF(sys),"stuff",data...);   *     or fprintf(MIF(sys),"stuff",data...);
1007   *  Use of these is requested on grounds of readability but not required.   *  Use of these is requested on grounds of readability but not required.
1008   *  MIF and LIF are macros, which means any specific solver interface   *  All of these are macros, which means any specific solver interface
1009   *  to ASCEND can use them, since all interfaces are supposed to   *  to ASCEND can use them, since all interfaces are supposed to
1010   *  support a parameters structure p somewhere in a larger system   *  support a parameters structure p somewhere in a larger system
1011   *  structure (sys) they keep privately.   *  structure (sys) they keep privately.
# Line 806  extern FILE *slv_get_output_file(FILE *f Line 1013  extern FILE *slv_get_output_file(FILE *f
1013   *  rather than a in-struct member.   *  rather than a in-struct member.
1014   */   */
1015  #define MIF(sys) slv_get_output_file( (sys)->p.output.more_important )  #define MIF(sys) slv_get_output_file( (sys)->p.output.more_important )
1016  /**<  /**<
1017   *  Retrieve the "more important" output file for a system.   *  Retrieve the "more important" output file for a system.
1018   *  sys must exist and contain an element p of type slv_parameters_t.   *  sys must exist and contain an element p of type slv_parameters_t.
1019     *
1020     *  @param sys The slv_system_t to query.
1021     *  @return A FILE * to the "more important" output file for sys.
1022   */   */
1023  #define LIF(sys) slv_get_output_file( (sys)->p.output.less_important )  #define LIF(sys) slv_get_output_file( (sys)->p.output.less_important )
1024  /**<  /**<
1025   *  Retrieve the "less important" output file for a system.   *  Retrieve the "less important" output file for a system.
1026   *  sys must exist and contain an element p of type slv_parameters_t.   *  sys must exist and contain an element p of type slv_parameters_t.
1027     *
1028     *  @param sys The slv_system_t to query.
1029     *  @return A FILE * to the "less important" output file for sys.
1030   */   */
1031  #define PMIF(sys) slv_get_output_file( (sys)->p->output.more_important )  #define PMIF(sys) slv_get_output_file( (sys)->p->output.more_important )
1032  /**<  /**<
1033   *  Retrieve the "more important" output file for a system.   *  Retrieve the "more important" output file for a system.
1034   *  sys must exist and contain an element p of type slv_parameters_t*.   *  sys must exist and contain an element p of type slv_parameters_t*.
1035     *
1036     *  @param sys The slv_system_t to query.
1037     *  @return A FILE * to the "more important" output file for sys.
1038   */   */
1039  #define PLIF(sys) slv_get_output_file( (sys)->p->output.less_important )  #define PLIF(sys) slv_get_output_file( (sys)->p->output.less_important )
1040  /**<  /**<
1041   *  Retrieve the "less important" output file for a system.   *  Retrieve the "less important" output file for a system.
1042   *  sys must exist and contain an element p of type slv_parameters_t*.   *  sys must exist and contain an element p of type slv_parameters_t*.
1043     *
1044     *  @param sys The slv_system_t to query.
1045     *  @return A FILE * to the "less important" output file for sys.
1046   */   */
1047    
1048  /*------------------- begin compiler dependent functions -------------------*/  /*------------------- begin compiler dependent functions -------------------*/
1049  #if SLV_INSTANCES  #if SLV_INSTANCES
1050    
 /**  
  *  void slv_print_obj_name(outfile,obj) [1/95: not yet implemented]  
  *  void slv_print_rel_name(outfile,sys,rel)  
  *  void slv_print_var_name(outfile,sys,var)  
  *  void slv_print_logrel_name(outfile,sys,lrel)  
  *  void slv_print_dis_name(outfile,sys,dvar)  
  *  
  *  Prints appropriate name.  If name can't be found by  
  *  *_make_name(*), the global index is printed by default.  
  *  
  *  void slv_print_obj_index(outfile,obj)[1/95: not yet implemented]  
  *  void slv_print_rel_sindex(outfile,rel)[1/95: not yet implemented]  
  *  void slv_print_var_sindex(outfile,var)[1/95: not yet implemented]  
  *  void slv_print_logrel_sindex(outfile,lrel)[1/95: not yet implemented]  
  *  void slv_print_dis_sindex(outfile,dvar)[1/95: not yet implemented]  
  *  
  *  To print the local index of a ***, call slv_print_***_index();  
  *  
  *  FILE *outfile;  
  *  obj_objective_t obj;  
  *  struct rel_relation *rel;  
  *  struct var_variable *var;  
  *  struct logrel_relation *lrel;  
  *  struct dis_discrete *dvar;  
  *  slv_system_t sys;  
  *  
  *  @todo Implement new functions or remove prototypes.  
  */  
1051  #ifdef NEWSTUFF  #ifdef NEWSTUFF
1052  extern void slv_print_obj_name(FILE *outfile, obj_objective_t obj);  extern void slv_print_obj_name(FILE *outfile, obj_objective_t obj);
1053  /**<  Prints the name of obj to outfile. */  /**<
1054     *  Not implemented.
1055     *  Prints the name of obj to outfile.  If obj_make_name() can't
1056     *  generate a name, the global index is printed instead.
1057     *  @todo Implement solver/slv_common:slv_print_obj_name() or remove prototype.
1058     */
1059  #endif  #endif
1060  extern void slv_print_rel_name(FILE *outfile,  extern void slv_print_rel_name(FILE *outfile,
1061                                 slv_system_t sys,                                 slv_system_t sys,
1062                                 struct rel_relation *rel);                                 struct rel_relation *rel);
1063  /**<  Prints the name of rel to outfile. */  /**<
1064     *  Prints the name of rel to outfile.  If rel_make_name() can't
1065     *  generate a name, the global index is printed instead.
1066     *
1067     *  @param outfile The stream to receive the output.
1068     *  @param sys     The solver system.
1069     *  @param rel     The relation whose name should be printed.
1070     *  @todo Move solver/slv_common:slv_print_rel_name() to solver/rel.
1071     */
1072    
1073  extern void slv_print_var_name(FILE *outfile,  extern void slv_print_var_name(FILE *outfile,
1074                                 slv_system_t sys,                                 slv_system_t sys,
1075                                 struct var_variable *var);                                 struct var_variable *var);
1076  /**<  Prints the name of var to outfile. */  /**<
1077     *  Prints the name of var to outfile. If var_make_name() can't
1078     *  generate a name, the global index is printed instead.
1079     *
1080     *  @param outfile The stream to receive the output.
1081     *  @param sys     The solver system.
1082     *  @param var     The variable whose name should be printed.
1083     *  @todo Move solver/slv_common:slv_print_var_name() to solver/var.
1084     */
1085    
1086  extern void slv_print_logrel_name(FILE *outfile,  extern void slv_print_logrel_name(FILE *outfile,
1087                                    slv_system_t sys,                                    slv_system_t sys,
1088                                    struct logrel_relation *lrel);                                    struct logrel_relation *lrel);
1089  /**<  Prints the name of lrel to outfile. */  /**<
1090     *  Prints the name of lrel to outfile. If logrel_make_name() can't
1091     *  generate a name, the global index is printed instead.
1092     *
1093     *  @param outfile The stream to receive the output.
1094     *  @param sys     The solver system.
1095     *  @param lrel    The logical relation whose name should be printed.
1096     *  @todo Move solver/slv_common:slv_print_logrel_name() to solver/logrel.
1097     */
1098    
1099  extern void slv_print_dis_name(FILE *outfile,  extern void slv_print_dis_name(FILE *outfile,
1100                                 slv_system_t sys,                                 slv_system_t sys,
1101                                 struct dis_discrete *dvar);                                 struct dis_discrete *dvar);
1102  /**<  Prints the name of dvar to outfile. */  /**<
1103     *  Prints the name of dvar to outfile. If dis_make_name() can't
1104     *  generate a name, the global index is printed instead.
1105     *
1106     *  @param outfile The stream to receive the output.
1107     *  @param sys     The solver system.
1108     *  @param dvar    The discrete variable whose name should be printed.
1109     *  @todo Move solver/slv_common:slv_print_dis_name() to solver/discrete.
1110     */
1111    
1112  #ifdef NEWSTUFF  #ifdef NEWSTUFF
1113  extern void slv_print_obj_index(FILE *outfile, obj_objective_t obj);  extern void slv_print_obj_index(FILE *outfile, obj_objective_t obj);
1114  /**<  Prints the index of obj to outfile. */  /**<
1115     *  Not implemented.
1116     *  Prints the index of obj to outfile.
1117     *  @todo Implement solver/slv_common:slv_print_obj_index() or remove prototype.
1118     */
1119  #endif  #endif
1120  extern void slv_print_rel_sindex(FILE *outfile, struct rel_relation *rel);  extern void slv_print_rel_sindex(FILE *outfile, struct rel_relation *rel);
1121  /**<  Prints the index of rel to outfile. */  /**<  
1122     *  Prints the index of rel to outfile.
1123     *
1124     *  @param outfile The stream to receive the output.
1125     *  @param rel     The relation whose index should be printed.
1126     *  @todo Move solver/slv_common:slv_print_rel_name() to solver/rel.
1127     */
1128    
1129  extern void slv_print_var_sindex(FILE *outfile, struct var_variable *var);  extern void slv_print_var_sindex(FILE *outfile, struct var_variable *var);
1130  /**<  Prints the index of var to outfile. */  /**<
1131     *  Prints the index of var to outfile.
1132     *
1133     *  @param outfile The stream to receive the output.
1134     *  @param var     The variable whose index should be printed.
1135     *  @todo Move solver/slv_common:slv_print_var_name() to solver/var.
1136     */
1137    
1138  extern void slv_print_logrel_sindex(FILE *outfile, struct logrel_relation *lrel);  extern void slv_print_logrel_sindex(FILE *outfile, struct logrel_relation *lrel);
1139  /**<  Prints the index of lrel to outfile. */  /**<  
1140  extern void slv_print_dis_sindex(FILE *outfile, struct dis_discrete *dvar);   *  Prints the index of lrel to outfile.
1141  /**<  Prints the index of dvar to outfile. */   *
1142     *  @param outfile The stream to receive the output.
1143     *  @param lrel    The logical relation whose index should be printed.
1144     *  @todo Move solver/slv_common:slv_print_logrel_name() to solver/logrel.
1145     */
1146    
1147  /**  extern void slv_print_dis_sindex(FILE *outfile, struct dis_discrete *dvar);
1148   *  <!--  int slv_direct_solve(server,rel,var,file,epsilon,ignore_bounds,scaled) -->  /**<
1149   *  <!--  struct rel_relation *rel;                                    -->   *  Prints the index of dvar to outfile.
  *  <!--  struct var_variable *var;                                    -->  
  *  <!--  boolean ignore_bounds;                                       -->  
  *  <!--  real64 epsilon;                                              -->  
1150   *   *
1151   *  Attempt to directly solve the given relation (equality constraint) for   *  @param outfile The stream to receive the output.
1152     *  @param dvar    The discrete variable whose index should be printed.
1153     *  @todo Move solver/slv_common:slv_print_dis_name() to solver/discrete.
1154     */
1155    
1156    extern int slv_direct_solve(slv_system_t server,
1157                                struct rel_relation *rel,
1158                                struct var_variable *var,
1159                                FILE *file,
1160                                real64 epsilon,
1161                                int ignore_bounds,
1162                                int scaled);
1163    /**<
1164     *  Attempts to directly solve the given relation (equality constraint) for
1165   *  the given variable, leaving the others fixed.  Returns an integer   *  the given variable, leaving the others fixed.  Returns an integer
1166   *  signifying the status as one of the following three:   *  signifying the status as one of the following three:
1167   *  <pre>   *  <pre>
# Line 912  extern void slv_print_dis_sindex(FILE *o Line 1175  extern void slv_print_dis_sindex(FILE *o
1175   *  </pre>   *  </pre>
1176   *  The variable bounds will be upheld, unless ignore_bounds=FALSE.   *  The variable bounds will be upheld, unless ignore_bounds=FALSE.
1177   *  Residual testing will be against epsilon and either scaled or   *  Residual testing will be against epsilon and either scaled or
1178   *  unscaled residual according to scaled (no scale <- 0)..   *  unscaled residual according to scaled (no scale -> 0).
1179   *  If file != NULL and there are leftover possible solutions, we   *  If file != NULL and there are leftover possible solutions, we
1180   *  will write about them to file.   *  will write about them to file.
1181     *
1182     *  @param server        The slv_system_t (mostly ignored).
1183     *  @param rel           The relation to attempt to solve.
1184     *  @param var           The variable for which to solve.
1185     *  @param file          File stream to receive other possible solutions.
1186     *  @param epsilon       Tolerance for testing convergence.
1187     *  @param ignore_bounds If TRUE, ignore bounds on variable.
1188     *  @param scaled        If TRUE, test scaled residuals against epsilon.
1189     *  @todo solver/slv_common:slv_direct_solve() should be in solver/relman
1190     *        or solver/slv3.
1191   */   */
 extern int slv_direct_solve(slv_system_t server,  
                             struct rel_relation *rel,  
                             struct var_variable *var,  
                             FILE *file,  
                             real64 epsilon,  
                             int ignore_bounds,  
                             int scaled);  
1192    
1193  /**  extern int slv_direct_log_solve(slv_system_t sys,
1194   *  <!--  int slv_direct_log_solve(server,lrel,dvar,file,perturb,insts)-->                                  struct logrel_relation *lrel,
1195   *  <!--  struct logrel_relation *lrel;                                -->                                  struct dis_discrete *dvar,
1196   *  <!--  struct dis_discrete *dvar;                                   -->                                  FILE *file,
1197   *                                  int perturb,
1198                                    struct gl_list_t *instances);
1199    /**<
1200   *  Attempt to directly solve the given logrelation for the given   *  Attempt to directly solve the given logrelation for the given
1201   *  discrete variable, leaving the others fixed.  Returns an integer   *  discrete variable, leaving the others fixed.  Returns an integer
1202   *  signifying the status as one of the following three:   *  signifying the status as one of the following three:
# Line 944  extern int slv_direct_solve(slv_system_t Line 1212  extern int slv_direct_solve(slv_system_t
1212   *  The flag perturb and the gl_list are used to change the truth   *  The flag perturb and the gl_list are used to change the truth
1213   *  value of some boundaries. This is sometimes useful in   *  value of some boundaries. This is sometimes useful in
1214   *  conditional modeling.   *  conditional modeling.
1215     *
1216     *  @param sys        The slv_system_t (mostly ignored).
1217     *  @param lrel       The logical relation to attempt to solve.
1218     *  @param dvar       The discrete variable for which to solve.
1219     *  @param file       File stream to receive other possible solutions.
1220     *  @param perturb    If TRUE, perturbs the truth values if necessary to find the solution.
1221     *  @param instances  List of instances.
1222     *  @todo solver/slv_common:slv_direct_log_solve() should be in solver/logrel
1223     *        or solver/slv9.
1224   */   */
 extern int slv_direct_log_solve(slv_system_t sys,  
                                 struct logrel_relation *lrel,  
                                 struct dis_discrete *dvar,  
                                 FILE *file,  
                                 int perturb,  
                                 struct gl_list_t *insts);  
1225    
1226  #endif  #endif
1227  /*-------------------- END compiler dependent functions --------------------*/  /*-------------------- END compiler dependent functions --------------------*/
1228    
1229  /*  /*
1230   *  lnkmap functions:   * --------------------
1231     *  lnkmap functions
1232     * --------------------
1233   */   */
1234    
1235  extern int32 **slv_create_lnkmap(int32 m, int32 n, int32 hl, int32 *hi, int32 *hj);  extern int32 **slv_create_lnkmap(int32 m, int32 n, int32 hl, int32 *hi, int32 *hj);
1236  /**<  /**<
1237   *  <!--  map=slv_create_lnkmap(m,n,hl,hi,hj);                         -->   *  Builds a row-biased mapping array from the hi,hj lists given.
  *  <!--  int32 m, n, hl                                               -->  
  *  <!--  int32 *hi, *hj                                               -->  
  *  <!--  int32 **map                                                  -->  
  *  
  *  Builds a row biased mapping array from the hi,hj lists given.  
1238   *  The map returned has the following format:   *  The map returned has the following format:
1239   *    - map[i] is a vector describing the incidence in row i of the matrix.   *    - map[i] is a vector describing the incidence in row i of the matrix.
1240   *    - Let vars=map[i], where vars is int32 *.   *    - Let vars=map[i], where vars is int32 *.
1241   *    - vars[0]=number of incidences in the relation.   *    - vars[0]=number of incidences in the relation.
1242   *    - For all 0<=k<vars[0]   *    - For all 0<=k<vars[0]
1243   *       - vars[2*k+1]= original column index of some var in the eqn.   *       - vars[2*k+1] = original column index of some var in the eqn.
1244   *       - vars[2*k+2]= the lnk list index of element(i,vars[2*k+1])   *       - vars[2*k+2] = the lnk list index of element(i,vars[2*k+1])
1245   *   *
1246   *  The map should only be deallocated by destroy_lnkmap().   *  The ordering of column data (i.e. vars[2*k+1]) is implementation-defined
1247   *  The memory allocation for a lnkmap is done efficiently.<br><br>   *  and should not be counted on.  Similarly, the lnk list index (i.e.
1248     *  vars[2*k+2]) will be a unique number in the range (0..hl-1), but the
1249     *  exact ordering is implementation-defined.  The map should only be
1250     *  deallocated by destroy_lnkmap().  The memory allocation for a lnkmap
1251     *  is done efficiently.<br><br>
1252   *   *
1253   *  These create an odd compressed row mapping, given the hi and hj   *  These create an odd compressed row mapping, given the hi and hj
1254   *  subscript vectors. The primary utility of the lnkmap is that   *  subscript vectors.  The primary utility of the lnkmap is that
1255   *  it can be traversed rapidly when one wants to conditionally map a row of   *  it can be traversed rapidly when one wants to conditionally map a row of
1256   *  a Harwell style (arbitrarily ordered) link representation   *  a Harwell style (arbitrarily ordered) link representation
1257   *  back into another representation where adding elements to a row   *  back into another representation where adding elements to a row
1258   *  is easily done.<br><br>   *  is easily done.<br><br>
1259   *   *
1260   *  hi and hj should specify a unique incidence pattern, that is no   *  hi and hj should specify a unique incidence pattern.  That is, duplicate
1261   *  duplicate elements are allowed.  Rowindex and colindex refer to   *  (hi, hj) coordinates are not allowed and only 1 of the occurrences will
1262   *  the data in hi,hj.   *  end up in the map.  hi should contain row indexes all less than m.  
1263   *   *  hj should contain column indexes all less than n.  If an invalid row/col
1264   *  @param m  The number of rows expected. The map returned will be this long.   *  index is encountered, NULL is returned.
1265   *  @param n  The number of columns expected.   *
1266     *  @param m  The number of rows expected (> highest index in hi).
1267     *            The map returned will be this long.
1268     *  @param n  The number of columns expected (> highest index in hj).
1269   *  @param hl The length of hi and hj.   *  @param hl The length of hi and hj.
1270   *  @param hi The eqn indices of a C numbered sparse matrix list.   *  @param hi The eqn indices of a C numbered sparse matrix list.
1271   *  @param hj The var indices of a C numbered sparse matrix list.   *  @param hj The var indices of a C numbered sparse matrix list.
1272     *  @return Pointer to the new lnkmap array, or NULL if an error occurred.
1273   */   */
1274    
1275  extern int32 **slv_lnkmap_from_mtx(mtx_matrix_t mtx, int32 len, int32 m);  extern int32 **slv_lnkmap_from_mtx(mtx_matrix_t mtx, mtx_region_t *region);
1276  /**<  /**<
1277   *  <!--  map=slv_lnkmap_from_mtx(mtx,len,m)                           -->   *  Generates a lnkmap from a region of a matrix.
1278   *  <!--  mtx_matrix_t mtx                                             -->   *  The length of the map returned will be the order of mtx.  Empty rows
1279   *  <!--  int32 len, m                                                 -->   *  and columns are allowed in the matrix.  Map entries for rows outside
1280   *  <!--  int32 **map                                                  -->   *  the specified region will be 0 even if the row contains non-zero
1281     *  elements.  If mtx is NULL, or if the region is invalid for mtx, then
1282     *  NULL is returned.<br><br>
1283   *   *
1284   *  Generates a map from a matrix.   *  The map returned has the following format:
1285   *  Empty rows and columns are allowed in the matrix.   *    - map[i] is a vector describing the incidence in row i of the matrix.
1286   *   *    - Let vars=map[i], where vars is int32 *.
1287   *  @param mtx  The matrix to map.   *    - vars[0]=number of non-zeros in the row.
1288   *  @param m    The number of rows expected. The map returned will be this long.   *    - For all 0<=k<vars[0]
1289   *  @param len  The number of nonzeros in mtx.   *       - vars[2*k+1] = original column index of some a non-zero element in the row.
1290     *       - vars[2*k+2] = the value of the element (i,vars[2*k+1]), cast to int32.
1291   *   *
1292   *  @see slv_create_lnkmap()   *  @param mtx    The matrix to map (non-NULL).
1293     *  @param region The region of the matrix to map (non-NULL).
1294     *  @return Pointer to the new lnkmap array, or NULL if an error occurred.
1295     *  @see slv_create_lnkmap() for a more details about lnkmaps.
1296   */   */
1297    
1298  extern void slv_destroy_lnkmap(int32 **map);  extern void slv_destroy_lnkmap(int32 **map);
1299  /**<  /**<
  *  <!--  slv_destroy_lnkmap(map);                                     -->  
  *  <!--  int32 **map                                                  -->  
  *  
1300   *  Deallocate a map created by slv_create_lnkmap() or slv_destroy_lnkmap().   *  Deallocate a map created by slv_create_lnkmap() or slv_destroy_lnkmap().
1301   *  destroy_lnkmap() will tolerate a NULL map as input.   *  destroy_lnkmap() will tolerate a NULL map as input.
1302     *
1303     *  @param map The lnkmap to destroy.
1304   */   */
1305    
1306  extern void slv_write_lnkmap(FILE *fp, int m, int32 **map);  extern void slv_write_lnkmap(FILE *fp, int m, int32 **map);
1307  /**<  /**<
1308   *  <!--  slv_write_lnkmap(fp,m,map);                                  -->   *  Prints a link map to a file.
  *  <!--  FILE *fp                                                     -->  
  *  <!--  int32 m (same as was created)                                -->  
  *  <!--  int32 **map                                                  -->  
  *  
  *  Print a link map.  
1309   *  write_lnkmap() will tolerate a NULL map as input.   *  write_lnkmap() will tolerate a NULL map as input.
1310     *
1311     *  @param fp  The file stream to receive the report.
1312     *  @param m   The number of rows in map to print.
1313     *  @param map The lnkmap to print.
1314   */   */
1315    
1316  #endif  /* slv_common__already_included */  #endif  /* slv_common__already_included */

Legend:
Removed from v.60  
changed lines
  Added in v.61

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22