eg_sloan.c

Go to the documentation of this file.
00001 #include "qs_config.h"
00002 #include "QSopt_ex.h"
00003 /* ========================================================================= */
00004 /** @name Static Variables
00005  * Set of static variables for this program. */
00006 /*@{*/
00007 /** @brief range of values for first OA level */
00008 static unsigned s1 = 3;
00009 /** @brief range of values for second OA level */
00010 static unsigned s2 = 3;
00011 /** @brief number of columns for first OA level */
00012 static unsigned k1 = 3;
00013 /** @brief number of columns for second OA level */
00014 static unsigned k2 = 3;
00015 /** @brief use (or not) scaling of the resulting LP */
00016 static int use_scaling = 1;
00017 /** @brief use dlouble floating point output */
00018 static int use_double = 0;
00019 /** @brief file name output. */
00020 const char *out_file = "output.lp";
00021 /** @brief Strength level required */
00022 static unsigned t = 2;
00023 /** @brief temporal string space */
00024 char strtmp[1024];
00025 /*@}*/
00026 
00027 /* ========================================================================= */
00028 /** @brief Display options to the screen */
00029 static inline void sl_usage (char const *const s)
00030 {
00031   fprintf (stderr,
00032            "This programs compute bounds for mixed-level orthogonal arrays (OA) of different strengths for two levels\n");
00033   fprintf (stderr, "Usage: %s [options]\n", s);
00034   fprintf (stderr, "    -a n   range of values for the first OA level (>=2)\n");
00035   fprintf (stderr,
00036            "    -b n   range of values for the second OA level (>=2)\n");
00037   fprintf (stderr,
00038            "    -c n   number of columns for the first OA level (>=2)\n");
00039   fprintf (stderr,
00040            "    -e n   number of columns for the second OA level (>=2)\n");
00041   fprintf (stderr,
00042            "    -d n   if n > 0, write the LP in double precition arithmetic, otherwise, write it in rational form\n");
00043   fprintf (stderr, "    -o f   filename where to write the output LP\n");
00044   fprintf (stderr,
00045            "    -s n   if n > 0 scale the resulting LP, otherwise present the unscaled LP\n");
00046   fprintf (stderr, "    -t n   required strength of the OA (>=1)\n");
00047 }
00048 
00049 /* ========================================================================= */
00050 /** @brief Display options to the screen */
00051 static inline int sl_parseargs (int argc,
00052                                 char **argv)
00053 {
00054   int c;
00055   while ((c = getopt (argc, argv, "a:b:c:e:s:d:o:t:")) != EOF)
00056   {
00057     switch (c)
00058     {
00059     case 'a':
00060       s1 = atoi (optarg);
00061       break;
00062     case 'b':
00063       s2 = atoi (optarg);
00064       break;
00065     case 'c':
00066       k1 = atoi (optarg);
00067       break;
00068     case 'e':
00069       k2 = atoi (optarg);
00070       break;
00071     case 's':
00072       use_scaling = atoi (optarg);
00073       break;
00074     case 'd':
00075       use_double = atoi (optarg);
00076       break;
00077     case 'o':
00078       out_file = optarg;
00079       break;
00080     case 't':
00081       t = atoi (optarg);
00082       break;
00083     default:
00084       sl_usage (argv[0]);
00085       return 1;
00086     }
00087   }
00088   if (s1 < 2 || s2 < 2 || k1 < 1 || k2 < 1 || t < 1)
00089   {
00090     sl_usage (argv[0]);
00091     return 1;
00092   }
00093   fprintf (stderr, "Running %s\nOptions:\n", argv[0]);
00094   fprintf (stderr, "\tfirst level columns = %d\n", k1);
00095   fprintf (stderr, "\tsecond level columns = %d\n", k2);
00096   fprintf (stderr, "\tfirst level range = %d\n", s1);
00097   fprintf (stderr, "\tsecond level range = %d\n", s2);
00098   fprintf (stderr, "\tt = %d\n", t);
00099   fprintf (stderr, "\t%s scaling\n", use_scaling ? "using" : "not using");
00100   fprintf (stderr, "\t%s output\n", use_double ? "double" : "rational");
00101   fprintf (stderr, "\toutput file : %s\n", out_file);
00102   return 0;
00103 }
00104 
00105 /* ========================================================================= */
00106 /** @brief compute the krawtchouk ppolynomial, defined as
00107  * \f[P^s_j(x,m)=\sum\limits_{i=0}^j(-1)^i(s-1)^{j-i}\binom{x}{i}\binom{m-x}{j-i}\f]
00108  * @param x the \f$x\f$ parameter of the function.
00109  * @param s the \f$s\f$ parameter of the function.
00110  * @param j the \f$j\f$ parameter of the function.
00111  * @param m the \f$m\f$ parameter of the function.
00112  * @param rop where to store the result */
00113 void Kpoly (unsigned x,
00114             unsigned s,
00115             unsigned j,
00116             unsigned m,
00117             mpz_t rop)
00118 {
00119   register unsigned i = j + 1;
00120   mpz_t z1,
00121     z2;
00122   mpz_init (z1);
00123   mpz_init (z2);
00124   mpz_set_ui (rop, (unsigned long)0);
00125   EXIT (m < x, "m < x! impossible!");
00126   EXIT (s < 1, "s < 1! impossible!");
00127   while (i--)
00128   {
00129     mpz_bin_uiui (z1, (unsigned long)x, (unsigned long)i);
00130     mpz_set (z2, z1);
00131     mpz_bin_uiui (z1, (unsigned long)(m - x), (unsigned long)(j - i));
00132     mpz_mul (z2, z2, z1);
00133     mpz_ui_pow_ui (z1, (unsigned long)(s - 1), (unsigned long)(j - i));
00134     mpz_mul (z2, z2, z1);
00135     if (i & 1U)
00136       mpz_sub (rop, rop, z2);
00137     else
00138       mpz_add (rop, rop, z2);
00139   }
00140   mpz_clear (z1);
00141   mpz_clear (z2);
00142 }
00143 
00144 /* ========================================================================= */
00145 /** @brief main function, here we build the LP, execute the options and exit */
00146 int main (int argc,
00147           char **argv)
00148 {
00149   int rval = 0;
00150   mpq_t v1,
00151     v2;
00152   mpq_QSdata *p_mpq = 0;
00153   dbl_QSdata *p_dbl = 0;
00154   register unsigned i,
00155     j,
00156     k,
00157     l;
00158   /* parse input */
00159   EGlib_info();
00160   EGlib_version();
00161   QSopt_ex_version();
00162   QSexactStart();
00163   rval = sl_parseargs (argc, argv);
00164   if (rval)
00165     return rval;
00166   mpq_init (v1);
00167   mpq_init (v2);
00168   /* create the problem with the appropriate number of variables and
00169    * constraints */
00170   snprintf (strtmp, (size_t)1023, "OA_SL_%d-%d_%d-%d_t-%d", s1, k1, s2, k2, t);
00171   p_mpq = mpq_QScreate_prob (strtmp, QS_MIN);
00172   for (i = 0; i <= k1; i++)
00173     for (j = 0; j <= k2; j++)
00174     {
00175       snprintf (strtmp, (size_t)1023, "V_%d_%d", i, j);
00176       rval =
00177         mpq_QSnew_col (p_mpq, mpq_oneLpNum,
00178                        (i + j == 0) ? mpq_oneLpNum : mpq_zeroLpNum,
00179                        mpq_ILL_MAXDOUBLE, strtmp);
00180       CHECKRVALG (rval, CLEANUP);
00181       strtmp[0] = 'C';
00182       rval = mpq_QSnew_row (p_mpq, mpq_zeroLpNum,
00183                        ((i + j >= 1) && (i + j <= t)) ? 'E' : 'G', strtmp);
00184       CHECKRVALG (rval, CLEANUP);
00185     }
00186   /* now set the coefficients */
00187   for (i = 0; i <= k1; i++)
00188     for (j = 0; j <= k2; j++)
00189       for (k = 0; k <= k1; k++)
00190         for (l = 0; l <= k2; l++)
00191         {
00192           Kpoly (k, s1, i, k1, mpq_numref (v2));
00193           Kpoly (l, s2, j, k2, mpq_numref (v1));
00194           mpq_mul (v1, v1, v2);
00195           if (mpz_cmp_ui (mpq_numref (v1), (unsigned long)0))
00196           {
00197             rval =
00198               mpq_QSchange_coef (p_mpq, ((int)(j + i * (k2 + 1))), (int)(l + k * (k2 + 1)), v1);
00199             CHECKRVALG (rval, CLEANUP);
00200           }
00201         }
00202   /* now, if we are using scaling, we scale the non-zeros */
00203   if (use_scaling)
00204   {
00205     mpq_set_ui (v1, (unsigned long)1, (unsigned long)1);
00206     EXutilSimplify ((unsigned)(p_mpq->qslp->A.matsize), p_mpq->qslp->A.matval, v1);
00207     mpq_div (v2, mpq_oneLpNum, v1);
00208     fprintf (stderr, "Scale factor %lf\n", mpq_get_d (v2));
00209   }
00210   /* now we save the LP */
00211   if (use_double)
00212   {
00213     snprintf (strtmp, (size_t)1023, "OA_SL_%d-%d_%d-%d_t-%d", s1, k1, s2, k2, t);
00214     p_dbl = QScopy_prob_mpq_dbl (p_mpq, strtmp);
00215     rval = dbl_QSwrite_prob (p_dbl, out_file, "LP");
00216     CHECKRVALG (rval, CLEANUP);
00217   }
00218   else
00219   {
00220     rval = mpq_QSwrite_prob (p_mpq, out_file, "LP");
00221     CHECKRVALG (rval, CLEANUP);
00222   }
00223 
00224   /* ending */
00225 CLEANUP:
00226   if (p_mpq)
00227     mpq_QSfree_prob (p_mpq);
00228   if (p_dbl)
00229     dbl_QSfree_prob (p_dbl);
00230   mpq_clear (v1);
00231   mpq_clear (v2);
00232   QSexactClear();
00233   return rval;
00234 }

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