fp20_write_lp.c

Go to the documentation of this file.
00001 /****************************************************************************/
00002 /*                                                                          */
00003 /*  This file is part of QSopt_ex.                                          */
00004 /*                                                                          */
00005 /*  (c) Copyright 2006 by David Applegate, William Cook, Sanjeeb Dash,      */
00006 /*  and Daniel Espinoza                                                     */
00007 /*                                                                          */
00008 /*  Sanjeeb Dash ownership of copyright in QSopt_ex is derived from his     */
00009 /*  copyright in QSopt.                                                     */
00010 /*                                                                          */
00011 /*  This code may be used under the terms of the GNU General Public License */
00012 /*  (Version 2.1 or later) as published by the Free Software Foundation.    */
00013 /*                                                                          */
00014 /*  Alternatively, use is granted for research purposes only.               */
00015 /*                                                                          */
00016 /*  It is your choice of which of these two licenses you are operating      */
00017 /*  under.                                                                  */
00018 /*                                                                          */
00019 /*  We make no guarantees about the correctness or usefulness of this code. */
00020 /*                                                                          */
00021 /****************************************************************************/
00022 
00023 /* RCS_INFO = "$RCSfile: wr_lp.c,v $ $Revision: 1.2 $ $Date: 2003/11/05 16:49:52 $"; */
00024 
00025 /****************************************************************************/
00026 /*                                                                          */
00027 /*               Routines to support writing of LP files                    */
00028 /*                                                                          */
00029 /****************************************************************************/
00030 
00031 /* 
00032  * -) anything after '\' is comment 
00033  * -) variables consist of a-z A-Z 0-9!"#$%(),;.?@_`'{}|~ 
00034  *    don't start with a digit or '.'
00035  */
00036 
00037 #include "config.h"
00038 #include "fp20_iqsutil.h"
00039 #include "fp20_lpdefs.h"
00040 #include "fp20_write_lp.h"
00041 #ifdef USEDMALLOC
00042 #include "dmalloc.h"
00043 #endif
00044 
00045 void fp20_ILLwrite_lp_state_init (
00046   fp20_ILLwrite_lp_state * line,
00047   const char *str)
00048 {
00049   line->total = 0;
00050   line->p = line->buf;
00051   *line->p = '\0';
00052   if (str != NULL)
00053   {
00054     fp20_ILLwrite_lp_state_append (line, str);
00055   }
00056 }
00057 
00058 void fp20_ILLwrite_lp_state_append (
00059   fp20_ILLwrite_lp_state * line,
00060   const char *str)
00061 {
00062   int len, rval = 0;
00063 
00064   ILL_FAILfalse (str, "Must have non NULL string");
00065   sprintf (line->p, str);
00066   len = strlen (line->p);
00067   line->total += len;
00068   line->p += len;
00069 CLEANUP:
00070   return;
00071 }
00072 
00073 void fp20_ILLwrite_lp_state_append_coef (
00074   fp20_ILLwrite_lp_state * line,
00075   EGfp20_t v,
00076   int cnt)
00077 {
00078   EGfp20_t ntmp;
00079   int len = 0;
00080 
00081   fp20_EGlpNumInitVar (ntmp);
00082   fp20_EGlpNumCopy (ntmp, v);
00083   if (fp20_EGlpNumIsLessZero (ntmp))
00084   {
00085     sprintf (line->p, " - ");
00086     len = 3;
00087     fp20_EGlpNumSign (ntmp);
00088   }
00089   else
00090   {
00091     if (cnt > 0)
00092     {
00093       sprintf (line->p, " + ");
00094       len = 3;
00095     }
00096     else
00097     {
00098       sprintf (line->p, " ");
00099       len = 1;
00100     }
00101   }
00102   line->p += len;
00103   line->total += len;
00104   if (fp20_EGlpNumIsNeqq (ntmp, fp20_oneLpNum))
00105   {
00106     fp20_ILLwrite_lp_state_append_number (line, ntmp);
00107   }
00108   fp20_EGlpNumClearVar (ntmp);
00109 }
00110 
00111 /* so that diff will not stumble over too many number format differences 
00112  * between c and java generated lp files we make here sure that doubles 
00113  * which are printed without a ".xxx" part get ".0" from us
00114  */
00115 static void fp20_append_number (
00116   fp20_ILLwrite_lp_state * line,
00117   EGfp20_t v);
00118 void fp20_ILLwrite_lp_state_append_number (
00119   fp20_ILLwrite_lp_state * line,
00120   EGfp20_t v)
00121 {
00122   /* write a blank after 'inf' in case it is used as a coefficient and 
00123    * a variable follows */
00124   if (fp20_EGlpNumIsEqqual (v, fp20_ILL_MAXDOUBLE))
00125   {
00126     fp20_ILLwrite_lp_state_append (line, "inf ");
00127   }
00128   else
00129   {
00130     if (fp20_EGlpNumIsEqqual (v, fp20_ILL_MINDOUBLE))
00131     {
00132       fp20_ILLwrite_lp_state_append (line, "-inf ");
00133     }
00134     else
00135       fp20_append_number (line, v);
00136   }
00137 }
00138 
00139 static void fp20_append_number (
00140   fp20_ILLwrite_lp_state * line,
00141   EGfp20_t v)
00142 {
00143   int len = 0;
00144   char *numstr = fp20_EGlpNumGetStr (v);
00145 
00146   sprintf (line->p, "%s%n", numstr, &len);
00147   EGfree (numstr);
00148   line->p += len;
00149   line->total += len;
00150 }
00151 
00152 #if 0
00153 #define D_SCALE (1e9)
00154 static void fp20_append_number (
00155   fp20_ILLwrite_lp_state * line,
00156   double x)
00157 {
00158   /* Better code for writing rational problems */
00159   int i, k;
00160   int got = 0;
00161   double w, t;
00162   int nnum = 0;
00163   int nden = 0;
00164 
00165   if (x != 0.0)
00166   {
00167     if (x < 0.0)
00168       w = -x;
00169     else
00170       w = x;
00171 
00172     for (i = -9, t = 0.000000001; i <= 7; i++, t *= 10.0)
00173     {
00174       if (w >= t && w <= t * 10)
00175       {
00176         got = 1;
00177         break;
00178       }
00179     }
00180     if (got == 0)
00181     {
00182       fprintf (stderr, "Out-of-range number: %f\n", x);
00183       exit (1);
00184     }
00185   }
00186 
00187   if (x < 0.0)
00188   {
00189     sprintf (line->p, "-");
00190     line->p++;
00191     line->total++;
00192     x = -x;
00193   }
00194 
00195   while (x >= 10.0 * D_SCALE)
00196   {
00197     x /= 10.0;
00198     nnum++;
00199   }
00200 
00201   /* (x != (double) (int) x) is a hack to let small integers print nicely */
00202 
00203   while (x < D_SCALE && x != (double) (int) x)
00204   {
00205     x *= 10.0;
00206     nden++;
00207   }
00208 
00209   sprintf (line->p, "%.0f%n", x, &k);
00210   line->p += k;
00211   line->total += k;
00212 
00213   for (i = 0; i < nnum; i++)
00214   {
00215     sprintf (line->p, "0");
00216     line->p++;
00217     line->total++;
00218   }
00219 
00220   if (nden)
00221   {
00222     sprintf (line->p, "/1%n", &k);
00223     line->p += k;
00224     line->total += k;
00225     for (i = 0; i < nden; i++)
00226     {
00227       sprintf (line->p, "0");
00228       line->p++;
00229       line->total++;
00230     }
00231   }
00232 }
00233 #endif
00234 
00235 void fp20_ILLwrite_lp_state_save_start (
00236   fp20_ILLwrite_lp_state * line)
00237 {
00238   line->startlen = line->total;
00239 }
00240 
00241 void fp20_ILLwrite_lp_state_start (
00242   fp20_ILLwrite_lp_state * line)
00243 {
00244   int j;
00245 
00246   for (j = 0; j < line->startlen; j++)
00247   {
00248     line->buf[j] = ' ';
00249   }
00250   line->buf[j] = '\0';
00251   line->p = line->buf + j;
00252   line->total = j;
00253 }

Generated on Thu Mar 29 09:32:30 2012 for QSopt_ex by  doxygen 1.4.7