- Timestamp:
- Apr 27, 1998, 11:11:56 AM (26 years ago)
- Branches:
- (u'spielwiese', 'd1b01e9d51ade4b46b745d3bada5c5f3696be3a8')
- Children:
- cc9f9695a5b671762065df870b39246130a3190f
- Parents:
- 72e211d33796504b757d1109ef77072d7e69fa30
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
Singular/weight.cc
r72e211 r104fd57 2 2 * Computer Algebra System SINGULAR * 3 3 ****************************************/ 4 /* $Id: weight.cc,v 1. 6 1997-12-15 22:46:43 obachmanExp $ */4 /* $Id: weight.cc,v 1.7 1998-04-27 09:11:56 pohl Exp $ */ 5 5 6 6 /* … … 25 25 pFDegProc pFDegOld; 26 26 pLDegProc pLDegOld; 27 #ifndef __MWERKS__ 27 28 extern "C" double (*wFunctional)(int *degw, int *lpol, int npol, 28 29 double *rel, double wx); … … 39 40 int npol, int mons, double *rel, double *fk); 40 41 extern "C" void wGcd(int *x, int n); 41 42 43 42 extern double nsqr; 43 #else 44 short * ecartWeights=NULL; 45 extern int pVariables; 46 47 static double * wDouble(void *adr) 48 { 49 long i = (long)adr; 50 return (double *)((i+7)&(~7)); 51 } 52 53 double nsqr; 54 double (*wFunctional)(int *degw, int *lpol, int npol, 55 double *rel, double wx); 56 57 58 static double wFunctionalMora(int *degw, int *lpol, int npol, 59 double *rel, double wx) 60 { 61 int i, j, e1, ecu, ecl, ec; 62 int *ex; 63 double gfmax, gecart, ghom, pfmax; 64 double *r; 65 66 ex = degw; 67 r = rel; 68 gfmax = (double)0.0; 69 gecart = (double)0.4 + (double)npol; 70 ghom = (double)1.0; 71 for (i = 0; i < npol; i++) 72 { 73 ecl = ecu = e1 = *ex++; 74 for (j = lpol[i] - 1; j; j--) 75 { 76 ec = *ex++; 77 if (ec > ecu) 78 ecu = ec; 79 else if (ec < ecl) 80 ecl = ec; 81 } 82 pfmax = (double)ecl / (double)ecu; 83 if (pfmax < ghom) 84 ghom = pfmax; 85 pfmax = (double)e1 / (double)ecu; 86 if (pfmax > (double)0.5) 87 gecart -= (pfmax * pfmax); 88 else 89 gecart -= (double)0.25; 90 ecu = 2 * ecu - ecl; 91 gfmax += (double)(ecu * ecu) * (*r++); 92 } 93 if (ghom > (double)0.8) 94 { 95 ghom *= (double)5.0; 96 gecart *= ((double)5.0 - ghom); 97 } 98 return (gfmax * gecart) / pow(wx, nsqr); 99 } 100 101 102 static double wFunctionalBuch(int *degw, int *lpol, int npol, 103 double *rel, double wx) 104 { 105 int i, j, ecl, ecu, ec; 106 int *ex; 107 double gfmax, ghom, pfmax; 108 double *r; 109 110 ex = degw; 111 r = rel; 112 gfmax = (double)0.0; 113 ghom = (double)1.0; 114 for (i = 0; i < npol; i++) 115 { 116 ecu = ecl = *ex++; 117 for (j = lpol[i] - 1; j; j--) 118 { 119 ec = *ex++; 120 if (ec < ecl) 121 ecl = ec; 122 else if (ec > ecu) 123 ecu = ec; 124 } 125 pfmax = (double)ecl / (double)ecu; 126 if (pfmax < ghom) 127 ghom = pfmax; 128 gfmax += (double)(ecu * ecu) * (*r++); 129 } 130 if (ghom > (double)0.5) 131 gfmax *= ((double)1.0 - (ghom * ghom)) / (double)0.75; 132 return gfmax / pow(wx, nsqr); 133 } 134 135 136 static void wSub(int *A, int mons, int kn, int xx) 137 { 138 int i, *B, *ex; 139 140 B = A + ((kn - 1) * mons); 141 ex = A + (pVariables * mons); 142 if (xx == 1) 143 { 144 for (i = mons; i; i--) 145 *ex++ -= *B++; 146 } 147 else 148 { 149 for (i = mons; i; i--) 150 *ex++ -= (*B++) * xx; 151 } 152 } 153 154 155 static void wAdd(int *A, int mons, int kn, int xx) 156 { 157 int i, *B, *ex; 158 159 B = A + ((kn - 1) * mons); 160 ex = A + (pVariables * mons); 161 if (xx == 1) 162 { 163 for (i = mons; i; i--) 164 *ex++ += *B++; 165 } 166 else 167 { 168 for (i = mons; i; i--) 169 *ex++ += (*B++) * xx; 170 } 171 } 172 173 174 static void wFirstSearch(int *A, int *x, int mons, 175 int *lpol, int npol, double *rel, double *fopt) 176 { 177 int a0, a, n, xn, t, xx, y1; 178 int *y, *degw, *xopt; 179 double fy, fmax, wx; 180 double *pr; 181 void *adr; 182 183 fy = *fopt; 184 n = pVariables; 185 xn = n + 6 + (21 / n); 186 a0 = n * sizeof(double) + 8; 187 a = n * sizeof(int); 188 y = (int * )Alloc(a); 189 adr = (void * )Alloc(a0); 190 pr = wDouble(adr); 191 *pr = (double)1.0; 192 *y = 0; 193 degw = A + (n * mons); 194 xopt = x + (n + 2); 195 t = 1; 196 loop 197 { 198 while (t < n) 199 { 200 xx = x[t] + 1; 201 wx = pr[t-1] * (double)xx; 202 y1 = y[t-1] + xx; 203 if ((y1 + n - t) <= xn) 204 { 205 pr[t] = wx; 206 y[t] = y1; 207 x[t] = xx; 208 if (xx > 1) 209 wAdd(A, mons, t, 1); 210 t++; 211 } 212 else 213 { 214 xx = x[t] - 1; 215 x[t] = 0; 216 if (xx!=0) 217 wSub(A, mons, t, xx); 218 t--; 219 if (t==0) 220 { 221 *fopt = fy; 222 Free((ADDRESS)y, a); 223 Free((ADDRESS)adr, a0); 224 return; 225 } 226 } 227 } 228 xx = xn - y[t-1]; 229 wx = pr[t-1] * (double)xx; 230 x[t] = xx; 231 xx--; 232 if (xx!=0) 233 wAdd(A, mons, t, xx); 234 fmax = (*wFunctional)(degw, lpol, npol, rel, wx); 235 if (xx!=0) 236 wSub(A, mons, t, xx); 237 if (fmax < fy) 238 { 239 fy = fmax; 240 memcpy(xopt, x + 1, a); 241 } 242 t--; 243 } /* end loop */ 244 } 245 246 247 static double wPrWeight(int *x, int n) 248 { 249 int i; 250 double y; 251 252 y = (double)x[n]; 253 for (i = n - 1; i; i--) 254 y *= (double)x[i]; 255 return y; 256 } 257 258 259 static void wEstimate(int *A, int *x, int *lpol, int npol, int mons, 260 double wx, double *rel, double *fopt, int *s0, int *s1, int *s2) 261 { 262 int n, i1, i2, k0 = 0, k1 = 0, k2 = 0; 263 int *degw; 264 double fo1, fo2, fmax, wx1, wx2; 265 266 n = pVariables; 267 degw = A + (n * mons); 268 fo2 = fo1 = (double)1.0e10; 269 for (i1 = n; i1; i1--) 270 { 271 if (x[i1] > 1) 272 { 273 wSub(A, mons, i1, 1); 274 wx1 = wx - wx / (double)x[i1]; 275 x[i1]--; 276 fmax = (*wFunctional)(degw, lpol, npol, rel, wx1); 277 if (fmax < fo1) 278 { 279 fo1 = fmax; 280 k0 = i1; 281 } 282 for (i2 = i1; i2; i2--) 283 { 284 if (x[i2] > 1) 285 { 286 wSub(A, mons, i2, 1); 287 wx2 = wx1 - wx1 / (double)x[i2]; 288 fmax = (*wFunctional)(degw, lpol, npol, rel, wx2); 289 if (fmax < fo2) 290 { 291 fo2 = fmax; 292 k1 = i1; 293 k2 = i2; 294 } 295 wAdd(A, mons, i2, 1); 296 } 297 } 298 wAdd(A, mons, i1, 1); 299 x[i1]++; 300 } 301 } 302 if (fo1 < fo2) 303 { 304 *fopt = fo1; 305 *s0 = k0; 306 } 307 else 308 { 309 *fopt = fo2; 310 *s0 = 0; 311 } 312 *s1 = k1; 313 *s2 = k2; 314 } 315 316 317 static void wSecondSearch(int *A, int *x, int *lpol, 318 int npol, int mons, double *rel, double *fk) 319 { 320 int n, s0, s1, s2, *xopt; 321 double one, fx, fopt, wx; 322 323 n = pVariables; 324 xopt = x + (n + 2); 325 fopt = *fk * (double)0.999999999999; 326 wx = wPrWeight(x, n); 327 one = (double)1.0; 328 loop 329 { 330 wEstimate(A, x, lpol, npol, mons, wx, rel, &fx, &s0, &s1, &s2); 331 if (fx > fopt) 332 { 333 if (s0!=0) 334 x[s0]--; 335 else if (s1!=0) 336 { 337 x[s1]--; 338 x[s2]--; 339 } 340 else 341 break; 342 } 343 else 344 { 345 fopt = fx; 346 if (s0!=0) 347 { 348 x[s0]--; 349 memcpy(xopt, x + 1, n * sizeof(int)); 350 if (s1==0) 351 break; 352 } 353 else if (s1!=0) 354 { 355 x[s1]--; 356 x[s2]--; 357 memcpy(xopt, x + 1, n * sizeof(int)); 358 } 359 else 360 break; 361 } 362 if (s0!=0) 363 wSub(A, mons, s0, 1); 364 else 365 { 366 wSub(A, mons, s1, 1); 367 wSub(A, mons, s2, 1); 368 } 369 wx = wPrWeight(x, n); 370 } 371 *fk = fopt; 372 } 373 374 375 static void wGcd(int *x, int n) 376 { 377 int i, b, a, h; 378 379 i = n; 380 b = x[i]; 381 loop 382 { 383 i--; 384 if (i==0) 385 break; 386 a = x[i]; 387 if (a < b) 388 { 389 h = a; 390 a = b; 391 b = h; 392 } 393 do 394 { 395 h = a % b; 396 a = b; 397 b = h; 398 } 399 while (b!=0); 400 b = a; 401 if (b == 1) 402 return; 403 } 404 for (i = n; i; i--) 405 x[i] /= b; 406 } 407 408 409 static void wSimple(int *x, int n) 410 { 411 int g, min, c, d, f, kopt, k, i; 412 int *xopt; 413 double sopt, s1, s2; 414 415 xopt = x + (n + 1); 416 kopt = k = g = 0; 417 min = 1000000; 418 for (i = n; i; i--) 419 { 420 c = xopt[i]; 421 if (c > 1) 422 { 423 if (c < min) 424 min = c; 425 if (c > k) 426 k = c; 427 } 428 else 429 g = 1; 430 } 431 k -= min; 432 if ((g==0) && (k < 4)) 433 return; 434 if (k < min) 435 min = k+1; 436 sopt = (double)1.0e10; 437 for (k = min; k > 1; k--) 438 { 439 s2 = s1 = (double)0.0; 440 for(i = n; i; i--) 441 { 442 c = xopt[i]; 443 if (c > 1) 444 { 445 d = c / k; 446 d *= k; 447 f = d = c - d; 448 if (f!=0) 449 { 450 f = k - f; 451 if (f < d) 452 s2 += (double)f / (double)c; 453 else 454 s1 += (double)d / (double)c; 455 } 456 } 457 } 458 s1 += s2 + sqrt(s1 * s2); 459 s1 -= (double)0.01 * sqrt((double)k); 460 if (s1 < sopt) 461 { 462 sopt = s1; 463 kopt = k; 464 } 465 } 466 for(i = n; i; i--) 467 { 468 x[i] = 1; 469 c = xopt[i]; 470 if (c > 1) 471 { 472 d = c / kopt; 473 d *= kopt; 474 x[i] = d; 475 d = c - d; 476 if ((d!=0) && (kopt < 2 * d)) 477 x[i] += kopt; 478 } 479 } 480 if (g==0) 481 wGcd(x, n); 482 } 483 484 485 static void wNorm(int *degw, int *lpol, int npol, double *rel) 486 { 487 int i, j, ecu, ec; 488 int *ex; 489 double *r; 490 491 ex = degw; 492 r = rel; 493 for (i = 0; i < npol; i++) 494 { 495 ecu = *ex++; 496 for (j = lpol[i] - 1; j; j--) 497 { 498 ec = *ex++; 499 if (ec > ecu) 500 ecu = ec; 501 } 502 *r = (double)1.0 / (double)(ecu * ecu); 503 r++; 504 } 505 } 506 #endif /* __MWERKS */ 507 44 508 45 509 static void wDimensions(polyset s, int sl, int *lpol, int *npol, int *mons)
Note: See TracChangeset
for help on using the changeset viewer.