Esempio n. 1
0
/*
 * translate #1 or lx:ly,hx:hy into a result range struct
 * returns absolute coords
 */
int
sarg_area(char *str, struct range *rp)
{
    long rlm;
    struct natstr *np;
    struct realmstr realm;
    char *end;

    if (*str == '#') {
	/*
	 * realm #X where (X > 0 && X < MAXNOR)
	 * Assumes realms are in abs coordinates
	 */
	if (*++str) {
	    rlm = strtol(str, &end, 10);
	    if (end == str || (*end != 0 && !isspace(*end))
		|| rlm < 0 || MAXNOR <= rlm)
		return 0;
	} else
	    rlm = 0;
	getrealm(rlm, player->cnum, &realm);
	rp->lx = realm.r_xl;
	rp->hx = realm.r_xh;
	rp->ly = realm.r_yl;
	rp->hy = realm.r_yh;
    } else {
	/*
	 * full map specification
	 * LX:LY,HX:HY where
	 * ly, hy are optional.
	 */
	rp->lx = rp->hx = strtox(str, &str);
	if (rp->lx < 0)
	    return 0;
	if (*str == ':') {
	    rp->hx = strtox(str + 1, &str);
	    if (rp->hx < 0)
		return 0;
	}
	if (*str++ != ',')
	    return 0;
	rp->ly = rp->hy = strtoy(str, &str);
	if (rp->ly < 0)
	    return 0;
	if (*str == ':') {
	    rp->hy = strtoy(str + 1, &str);
	    if (rp->hy < 0)
		return 0;
	}
	if (*str != 0 && !isspace(*str))
	    return 0;
	np = getnatp(player->cnum);
	rp->lx = xabs(np, rp->lx);
	rp->hx = xabs(np, rp->hx);
	rp->ly = yabs(np, rp->ly);
	rp->hy = yabs(np, rp->hy);
    }
    xysize_range(rp);
    return 1;
}
Esempio n. 2
0
// COMPUTES L2 FIXED-SHIFT H POLYNOMIALS AND TESTS FOR CONVERGENCE.
// INITIATES A VARIABLE-SHIFT ITERATION AND RETURNS WITH THE
// APPROXIMATE ZERO IF SUCCESSFUL.
// L2 - LIMIT OF FIXED SHIFT STEPS
// ZR,ZI - APPROXIMATE ZERO IF CONV IS .TRUE.
// CONV  - LOGICAL INDICATING CONVERGENCE OF STAGE 3 ITERATION
//
static bool fxshft(const int l2, int deg, xcomplex *P, xcomplex *p, xcomplex *H, xcomplex *h, xcomplex *zero, xcomplex *s){
   bool bol, conv;	 	       // boolean for convergence of stage 2
   bool test, pasd;
   xcomplex old_T, old_S, Ps, t;
   xcomplex Tmp[deg+1];

   Ps = polyev(deg, *s, P, p);
   test = true;
   pasd = false;

   // Calculate first T = -P(S)/H(S)
   t = calct(&bol, deg, Ps, H, h, *s);

   // Main loop for second stage
   for(int j = 1; j <= l2; j++){
      old_T = t;

      // Compute the next H Polynomial and new t
      nexth(bol, deg, t, H, h, p);
      t = calct(&bol, deg, Ps, H, h, *s);
      *zero = *s + t;

      // Test for convergence unless stage 3 has failed once or this
      // is the last H Polynomial
      if(!(bol || !test || j == l2)){
         if(xabs(t - old_T) < 0.5 * xabs(*zero)) {
            if(pasd) {
               // The weak convergence test has been passwed twice, start the third stage
               // Iteration, after saving the current H polynomial and shift
               for(int i = 0; i < deg; i++) 
                  Tmp[i] = H[i]; 
               old_S = *s;

               conv = vrshft(10, deg, P, p, H, h, zero, s);
               if(conv) return conv;

               //The iteration failed to converge. Turn off testing and restore h,s,pv and T
               test = false;
               for(int i = 0; i < deg; i++)
                  H[i] = Tmp[i];
               *s = old_S;

               Ps = polyev(deg, *s, P, p);
               t = calct(&bol, deg, Ps, H, h, *s);
               continue;
               }
            pasd = true;
            }
         else
            pasd = false;
      }
   }

   // Attempt an iteration with final H polynomial from second stage
   conv = vrshft(10, deg, P, p, H, h, zero, s);
   return conv;
}
Esempio n. 3
0
// BOUNDS THE ERROR IN EVALUATING THE POLYNOMIAL BY THE HORNER RECURRENCE.
// QR,QI - THE PARTIAL SUMS
// MS    -MODULUS OF THE POINT
// MP    -MODULUS OF POLYNOMIAL VALUE
// ARE, MRE -ERROR BOUNDS ON COMPLEX ADDITION AND MULTIPLICATION
//
static xreal errev(const int deg, const xcomplex *p, const xreal ms, const xreal mp){
   xreal MRE = 2.0 * sqrt(2.0) * xeta(p[0]);
   xreal e =  xabs(p[0]) * MRE / (xeta(p[0]) + MRE);

   for(int i = 0; i <= deg; i++)
      e = e * ms + xabs(p[i]);
   
   return e * (xeta(p[0]) + MRE) - MRE * mp;
}
Esempio n. 4
0
/*
 * translate @x,y:int into
 * result params
 */
int
sarg_range(char *str, coord *xp, coord *yp, int *dist)
{
    coord x, y;
    long d;
    char *end;
    struct natstr *np;

    if (*str++ != '@')
	return 0;
    x = strtox(str, &str);
    if (x < 0 || *str++ != ',')
	return 0;
    y = strtoy(str, &str);
    if (y < 0 || *str++ != ':')
	return 0;
    d = strtol(str, &end, 10);
    if (end == str || (*end != 0 && !isspace(*end)) || d < 0)
	return 0;
    *dist = d;
    np = getnatp(player->cnum);
    *xp = xabs(np, x);
    *yp = yabs(np, y);
    return 1;
}
Esempio n. 5
0
struct cxpr
cxatanh (struct cxpr z)
{
  struct cxpr w;
  struct xpr t;
  int errcond;

  t = xadd (xabs (z.re), xOne, 1);
  errcond = xsgn (&z.im) == 0 && xsgn (&t) == 0;
  if (xsigerr (errcond, XEDOM, "cxatanh()"))
    return cxZero;
  else
    {
      w = cxdiv (cxsum (cxOne, z), cxsub (cxOne, z));
      w = cxlog_sqrt (w);
      return w;
    }
}
Esempio n. 6
0
// CAUCHY COMPUTES A LOWER BOUND ON THE MODULI OF THE ZEROS OF A
// POLYNOMIAL - PT IS THE MODULUS OF THE COEFFICIENTS.
//
static xcomplex cauchy(const int deg, xcomplex *P)
{
  xreal x, xm, f, dx, df, tmp[deg+1];

  for(int i = 0; i<=deg; i++){ tmp[i] = xabs(P[i]); };

  // Compute upper estimate bound
  x = xroot(tmp[deg],deg) / xroot(tmp[0],deg);
  if(tmp[deg - 1] != 0.0) {
    // Newton step at the origin is better, use it
    xm = tmp[deg] / tmp[deg-1];
    if (xm < x) x = xm;
  }
  
  tmp[deg] = -tmp[deg];

  // Chop the interval (0,x) until f < 0
  while(1) {
    xm = x * 0.1;
    // Evaluate the polynomial <tmp> at <xm>
    f = tmp[0];
    for(int i = 1; i <= deg; i++)
      f = f * xm + tmp[i];
    
    if(f <= 0.0) break;
    x = xm;
  }
  dx = x;
   
   // Do Newton iteration until x converges to two decimal places
  while(fabs(dx / x) > 0.005) {
    f  = tmp[0];
    df = 0.0;
    for(int i = 1; i <= deg; i++){
      df = df * x + f;
      f  =  f * x + tmp[i];
    }
    
    dx = f / df;
    x -= dx;				// Newton step
  }

  return (xcomplex)(x);
}
Esempio n. 7
0
int
sarg_xy(char *str, coord *xp, coord *yp)
{
    coord x, y;
    struct natstr *np;

    x = strtox(str, &str);
    if (x < 0 || *str++ != ',')
	return 0;
    y = strtoy(str, &str);
    if (y < 0 || (*str != 0 && !isspace(*str)))
	return 0;
    if ((x ^ y) & 1)
	return 0;
    np = getnatp(player->cnum);
    *xp = xabs(np, x);
    *yp = yabs(np, y);
    return 1;
}
Esempio n. 8
0
/*
 * setup the nstr_sect structure for sector selection.
 * can select on either NS_ALL, NS_AREA, or NS_DIST
 * iterate thru the "condarg" string looking
 * for arguments to compile into the nstr.
 * Using this function for anything but command arguments is usually
 * incorrect, because it respects conditionals.  Use the snxtsct_FOO()
 * instead.
 */
int
snxtsct(struct nstr_sect *np, char *str)
{
    struct range range;
    struct natstr *natp;
    coord cx, cy;
    int dist;
    char buf[1024];

    if (!str || !*str) {
	if (!(str = getstring("(sects)? ", buf)))
	    return 0;
    } else
	make_stale_if_command_arg(str);
    switch (sarg_type(str)) {
    case NS_AREA:
	if (!sarg_area(str, &range))
	    return 0;
	snxtsct_area(np, &range);
	break;
    case NS_DIST:
	if (!sarg_range(str, &cx, &cy, &dist))
	    return 0;
	snxtsct_dist(np, cx, cy, dist);
	break;
    case NS_ALL:
	/*
	 * Can't use snxtsct_all(), as it would disclose the real
	 * origin.  Use a world-sized area instead.
	 */
	natp = getnatp(player->cnum);
	range.lx = xabs(natp, -WORLD_X / 2);
	range.ly = yabs(natp, -WORLD_Y / 2);
	range.hx = xnorm(range.lx + WORLD_X - 1);
	range.hy = ynorm(range.ly + WORLD_Y - 1);
	xysize_range(&range);
	snxtsct_area(np, &range);
	break;
    default:
	return 0;
    }
    return snxtsct_use_condarg(np);
}
Esempio n. 9
0
// CARRIES OUT THE THIRD STAGE ITERATION.
// L3 - LIMIT OF STEPS IN STAGE 3.
// ZR,ZI   - ON ENTRY CONTAINS THE INITIAL ITERATE, IF THE
//           ITERATION CONVERGES IT CONTAINS THE FINAL ITERATE ON EXIT.
// CONV    -  .TRUE. IF ITERATION CONVERGES
//
static bool vrshft(const int l3, int deg, xcomplex *P, xcomplex *p, xcomplex *H, xcomplex *h, xcomplex *zero, xcomplex *s){
  bool bol, conv, b;
  int i, j;
  xcomplex Ps, t;
  xreal mp, ms, omp = 0.0, relstp = 0.0, tp;

  conv = b = false;
  *s = *zero;

  // Main loop for stage three
  for(i = 1; i <= l3; i++) {
    // Evaluate P at S and test for convergence
    Ps = polyev(deg, *s, P, p);
    mp = xabs(Ps);
    ms = xabs(*s);
    if(mp <= 20 * errev(deg, p, ms, mp)) {
      // Polynomial value is smaller in value than a bound on the error
      // in evaluating P, terminate the iteration
      conv = true;
      *zero = *s;
      return conv;
    }
    
    if(i != 1) {
      if(!(b || mp < omp || relstp >= 0.05)){
	//       if(!(b || xlogb(mp) < omp || real(relstp) >= 0.05)){
	// Iteration has stalled. Probably a cluster of zeros. Do 5 fixed 
	// shift steps into the cluster to force one zero to dominate
	tp = relstp;
	b = true;
	if(relstp < xeta(P[0])) tp = xeta(P[0]);
	
	*s *= 1.0 + (1.0+1.0i)*sqrt(tp);

	Ps = polyev(deg, *s, P, p);
	for(j = 1; j <= 5; j++){
	  t = calct(&bol, deg, Ps, H, h, *s);
	  nexth(bol, deg, t, H, h, p);
	}
	omp = xdata.INFIN;
	goto _20;
      }
         
      // Exit if polynomial value increase significantly
      if(mp * 0.1 > omp) return conv;
    }
    
    omp = mp;

    // Calculate next iterate
  _20:  t = calct(&bol, deg, Ps, H, h, *s);
    nexth(bol, deg, t, H, h, p);
    t = calct(&bol, deg, Ps, H, h, *s);
    if(!bol) {
      relstp = xabs(t) / xabs(*s);
      *s += t;
    }
  } // end for
  
  return conv;
}