Overview Schemas Index

MATHEMATICAL_FUNCTIONS_SCHEMA (jsdai.SMathematical_functions_schema)


FUNCTION enclose_cregion_in_pregion
          (crgn : cartesian_complex_number_region, centre : complex_number_literal) : polar_complex_number_region;

FUNCTION angle(a : REAL) : REAL;
    REPEAT  WHILE  a > PI;    a := a - 2.0*PI;  END_REPEAT;
    REPEAT WHILE a <= -PI;  a := a + 2.0*PI;  END_REPEAT;
    RETURN  (a);
  END_FUNCTION;
  -- Determine whether a REAL  is strictly within a REAL  interval
  FUNCTION strictly_in(z    : REAL;
                       zitv : real_interval) : LOGICAL;
    RETURN  ((NOT min_exists(zitv) OR  (z > real_min(zitv))) AND
      (NOT max_exists(zitv) OR  (z < real_max(zitv))));
  END_FUNCTION;
  -- Include direction IN  minmax collection
  PROCEDURE  angle_minmax(    ab, a            : REAL;
                             a_in             : BOOLEAN;
                         VAR  amin, amax       : REAL;
                         VAR  amin_in, amax_in : BOOLEAN);
    a := angle(a - ab);
    IF  amin = a THEN   amin_in := amin_in OR  a_in;  END_IF;
    IF  amin > a THEN   amin := a;  amin_in := a_in;  END_IF;
    IF  amax = a THEN   amax_in := amax_in OR  a_in;  END_IF;
    IF  amax < a THEN   amax := a;  amax_in := a_in;  END_IF;
  END_PROCEDURE;
  -- Include distance IN  max collection
  PROCEDURE  range_max(    r       : REAL;
                          incl    : BOOLEAN;
                      VAR  rmax    : REAL;
                      VAR  rmax_in : BOOLEAN);
    IF  rmax = r THEN   rmax_in := rmax_in OR  incl;   END_IF;
    IF  rmax < r THEN   rmax := r;  rmax_in := incl;  END_IF;
  END_PROCEDURE;
  -- Include distance IN min collection
  PROCEDURE range_min(    r       : REAL;
                          incl    : BOOLEAN;
                      VAR  rmin    : REAL;
                      VAR rmin_in : BOOLEAN);
    IF  rmin = r THEN   rmin_in := rmin_in OR  incl;  END_IF;
    IF  (rmin < 0.0) OR  (rmin > r) THEN   rmin := r;  rmin_in := incl;  END_IF;
  END_PROCEDURE;
  LOCAL
    xitv, yitv : real_interval;
    is_xmin, is_xmax, is_ymin, is_ymax : BOOLEAN;
    xmin, xmax, ymin, ymax, xc, yc : REAL  := 0.0;
    xmin_in, xmax_in, ymin_in, ymax_in : BOOLEAN  := FALSE;
    rmin, rmax : REAL  := -1.0;
    amin : REAL  := 4.0;
    amax : REAL  := -4.0;
    rmax_exists, outside : BOOLEAN  := TRUE;
    rmin_in, rmax_in, amin_in, amax_in : BOOLEAN := FALSE;
    ab, a, r : REAL := 0.0;
    incl : BOOLEAN;
    ritv : real_interval;
    aitv : finite_real_interval;
    minclo, maxclo : open_closed := open;
  END_LOCAL;
  IF  NOT  EXISTS  (crgn) OR  NOT  EXISTS  (centre) THEN   RETURN  (?);  END_IF;
  -- Extract elementary input information
  xitv := crgn.real_constraint;
  yitv := crgn.imag_constraint;
  xc := centre.real_part;
  yc := centre.imag_part;
  is_xmin := min_exists(xitv);
  is_xmax := max_exists(xitv);
  is_ymin := min_exists(yitv);
  is_ymax := max_exists(yitv);
  IF  is_xmin THEN   xmin := real_min(xitv);  xmin_in := min_included(xitv);  END_IF;
  IF  is_xmax THEN   xmax := real_max(xitv);  xmax_in := max_included(xitv);  END_IF;
  IF  is_ymin THEN   ymin := real_min(yitv);  ymin_in := min_included(yitv);  END_IF;
  IF  is_ymax THEN   ymax := real_max(yitv);  ymax_in := max_included(yitv);  END_IF;
  rmax_exists := is_xmin AND  is_xmax AND  is_ymin AND  is_ymax;
  -- Identify base direction WITH respect TO  which all relevant directions lie
  -- within +/- 0.5*PI, OR that the centre lies properly inside crgn.
  IF        is_xmin AND  (xc <= xmin)  THEN   ab := 0.0;
  ELSE  IF   is_ymin AND  (yc <= ymin)  THEN   ab := 0.5*PI;
  ELSE  IF   is_ymax AND  (yc >= ymax)  THEN   ab := -0.5*PI;
  ELSE  IF   is_xmax AND  (xc >= xmax)  THEN   ab := PI;
  ELSE                                      outside := FALSE;
  END_IF;  END_IF;  END_IF;  END_IF;
  IF  NOT  outside AND  NOT  rmax_exists THEN
    RETURN  (?);  -- No enclosing polar region EXISTS (requires whole plane)
  END_IF;
  -- Identify any closest point on a side but NOT  a corner.
  IF        is_xmin AND  (xc <= xmin) AND  strictly_in(yc,yitv) THEN
    rmin := xmin - xc;  rmin_in := xmin_in;
  ELSE  IF   is_ymin AND  (yc <= ymin) AND  strictly_in(xc,xitv) THEN
    rmin := ymin - yc;  rmin_in := ymin_in;
  ELSE  IF   is_ymax AND  (yc >= ymax) AND  strictly_in(xc,xitv) THEN
    rmin := yc - ymax;  rmin_in := ymax_in;
  ELSE  IF   is_xmax AND  (xc >= xmax) AND  strictly_in(yc,yitv) THEN
    rmin := xc - xmax;  rmin_in := xmax_in;
  END_IF;  END_IF;  END_IF;  END_IF;
  IF  is_xmin THEN
    IF  is_ymin THEN   -- Consider lower left corner
      r := SQRT((xmin-xc)**2 + (ymin-yc)**2);
      incl := xmin_in AND  ymin_in;
      IF  rmax_exists THEN   range_max(r,incl,rmax,rmax_in);  END_IF;
      IF  outside THEN
        IF  r > 0.0 THEN
          range_min(r,incl,rmin,rmin_in);
          a := angle(atan2(ymin-yc,xmin-xc) - ab);
          IF  xc = xmin THEN   incl := xmin_in;  END_IF;
          IF  yc = ymin THEN   incl := ymin_in;  END_IF;
          angle_minmax(ab,a,incl,amin,amax,amin_in,amax_in);
        ELSE   -- Centre at lower left corner
          rmin := 0.0;                rmin_in := xmin_in AND  ymin_in;
          amin := angle(0.0-ab);      amin_in := ymin_in;
          amax := angle(0.5*PI-ab);   amax_in := xmin_in;
        END_IF;
      END_IF;
    ELSE  IF  xc <= xmin THEN   -- Consider points near (xmin, -infinity)
      angle_minmax(ab,-0.5*PI,(xc=xmin) AND  xmin_in,amin,amax,amin_in,amax_in);
    END_IF;  END_IF;
    IF  NOT  is_ymax AND  (xc <= xmin) THEN   -- Consider points near (xmin, +infinity)
      angle_minmax(ab,0.5*PI,(xc=xmin) AND  xmin_in,amin,amax,amin_in,amax_in);
    END_IF;
  END_IF;
  IF  is_ymin THEN
    IF  is_xmax THEN   -- Consider lower right corner
      r := SQRT((xmax-xc)**2 + (ymin-yc)**2);
      incl := xmax_in AND  ymin_in;
      IF  rmax_exists THEN   range_max(r,incl,rmax,rmax_in);  END_IF;
      IF  outside THEN
        IF  r > 0.0 THEN
          range_min(r,incl,rmin,rmin_in);
          a := angle(atan2(ymin-yc,xmax-xc) - ab);
          IF  xc = xmax THEN   incl := xmax_in;  END_IF;
          IF  yc = ymin THEN   incl := ymin_in;  END_IF;
          angle_minmax(ab,a,incl,amin,amax,amin_in,amax_in);
        ELSE   -- Centre at lower right corner
          rmin := 0.0;                rmin_in := xmax_in AND  ymin_in;
          amin := angle(0.5*PI-ab);   amin_in := ymin_in;
          amax := angle(PI-ab);       amax_in := xmax_in;
        END_IF;
      END_IF;
    ELSE  IF  yc <= ymin THEN   -- Consider points near (+infinity, ymin)
      angle_minmax(ab,0.0,(yc=ymin) AND  ymin_in,amin,amax,amin_in,amax_in);
    END_IF;  END_IF;
    IF  NOT  is_xmin AND  (yc <= ymin) THEN   -- Consider points near (-infinity, ymin)
      angle_minmax(ab,PI,(yc=ymin) AND  ymin_in,amin,amax,amin_in,amax_in);
    END_IF;
  END_IF;
  IF  is_xmax THEN
    IF  is_ymax THEN   -- Consider upper right corner
      r := SQRT((xmax-xc)**2 + (ymax-yc)**2);
      incl := xmax_in AND  ymax_in;
      IF  rmax_exists THEN   range_max(r,incl,rmax,rmax_in);  END_IF;
      IF  outside THEN
        IF  r > 0.0 THEN
          range_min(r,incl,rmin,rmin_in);
          a := angle(atan2(ymax-yc,xmax-xc) - ab);
          IF  xc = xmax THEN   incl := xmax_in;  END_IF;
          IF  yc = ymax THEN   incl := ymax_in;  END_IF;
          angle_minmax(ab,a,incl,amin,amax,amin_in,amax_in);
        ELSE   -- Centre at lower left corner
          rmin := 0.0;                rmin_in := xmax_in AND  ymax_in;
          amin := angle(-PI-ab);      amin_in := ymax_in;
          amax := angle(-0.5*PI-ab);  amax_in := xmax_in;
        END_IF;
      END_IF;
    ELSE  IF  xc >= xmax THEN   -- Consider points near (xmax, +infinity)
      angle_minmax(ab,0.5*PI,(xc=xmax) AND  xmax_in,amin,amax,amin_in,amax_in);
    END_IF;  END_IF;
    IF  NOT  is_ymin AND  (xc >= xmax) THEN   -- Consider points near (xmax, -infinity)
      angle_minmax(ab,-0.5*PI,(xc=xmax) AND  xmax_in,amin,amax,amin_in,amax_in);
    END_IF;
  END_IF;
  IF  is_ymax THEN
    IF  is_xmin THEN   -- Consider upper left corner
      r := SQRT((xmin-xc)**2 + (ymax-yc)**2);
      incl := xmin_in AND  ymax_in;
      IF  rmax_exists THEN   range_max(r,incl,rmax,rmax_in);  END_IF;
      IF  outside THEN
        IF  r > 0.0 THEN
          range_min(r,incl,rmin,rmin_in);
          a := angle(atan2(ymax-yc,xmin-xc) - ab);
          IF  xc = xmin THEN   incl := xmin_in;  END_IF;
          IF  yc = ymax THEN   incl := ymax_in;  END_IF;
          angle_minmax(ab,a,incl,amin,amax,amin_in,amax_in);
        ELSE   -- Centre at lower right corner
          rmin := 0.0;                rmin_in := xmin_in AND  ymax_in;
          amin := angle(0.5*PI-ab);   amin_in := ymax_in;
          amax := angle(PI-ab);       amax_in := xmin_in;
        END_IF;
      END_IF;
    ELSE IF  yc >= ymax THEN   -- Consider points near (-infinity, ymax)
      angle_minmax(ab,PI,(yc=ymax) AND  ymax_in,amin,amax,amin_in,amax_in);
    END_IF;  END_IF;
    IF  NOT is_xmax AND  (yc >= ymax) THEN   -- Consider points near (+infinity, ymax)
      angle_minmax(ab,0.0,(yc=ymax) AND ymax_in,amin,amax,amin_in,amax_in);
    END_IF;
  END_IF;
  IF  outside THEN   -- Change direction origin FROM ab back TO zero
    amin := angle(amin+ab);
    IF  amin = PI THEN   amin := -PI;  END_IF;
    amax := angle(amax+ab);
    IF  amax <= amin THEN   amax := amax + 2.0*PI;  END_IF;
  ELSE
    amin := -PI;  amin_in := FALSE;
    amax := PI;   amax_in := FALSE;
  END_IF;
  IF  amin_in THEN   minclo := closed;  END_IF;
  IF  amax_in THEN   maxclo := closed;  END_IF;
  aitv := make_finite_real_interval(amin,minclo,amax,maxclo);
  minclo := open;
  IF  rmin_in THEN   minclo := closed;  END_IF;
  IF  rmax_exists THEN
    maxclo := open;
    IF rmax_in THEN  maxclo := closed;  END_IF;
    ritv := make_finite_real_interval(rmin,minclo,rmax,maxclo);
  ELSE
    ritv := make_real_interval_from_min(rmin,minclo);
  END_IF;
  RETURN (make_polar_complex_number_region(centre,ritv,aitv));

END_FUNCTION; -- enclose_cregion_in_pregion

public class FEnclose_cregion_in_pregion
          public static Value run(SdaiContext _context, Value crgn, Value centre)