00001 #include "qs_config.h"
00002 #include "QSopt_ex.h"
00003
00004
00005
00006
00007
00008 static unsigned s1 = 3;
00009
00010 static unsigned s2 = 3;
00011
00012 static unsigned k1 = 3;
00013
00014 static unsigned k2 = 3;
00015
00016 static int use_scaling = 1;
00017
00018 static int use_double = 0;
00019
00020 const char *out_file = "output.lp";
00021
00022 static unsigned t = 2;
00023
00024 char strtmp[1024];
00025
00026
00027
00028
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
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
00107
00108
00109
00110
00111
00112
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
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
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
00169
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
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
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
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
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 }