[BACK]Return to predictors.adb CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / PHC / Ada / Continuation

Annotation of OpenXM_contrib/PHC/Ada/Continuation/predictors.adb, Revision 1.1

1.1     ! maekawa     1: with Standard_Mathematical_Functions;    use Standard_Mathematical_Functions;
        !             2: with Standard_Natural_Vectors;
        !             3: with Standard_Complex_Linear_Solvers;    use Standard_Complex_Linear_Solvers;
        !             4:
        !             5: package body Predictors is
        !             6:
        !             7: -- PREDICTORS for t :
        !             8:
        !             9:   procedure Real_Predictor
        !            10:               ( t : in out Complex_Number; target : in Complex_Number;
        !            11:                 h,tol : in double_float; pow : in positive := 1;
        !            12:                 hh : out double_float ) is
        !            13:
        !            14:     nt : Complex_Number;
        !            15:
        !            16:   begin
        !            17:     if pow = 1
        !            18:      then nt := t + Create(h);
        !            19:      else nt := Create((h+REAL_PART(t)**pow)**(1.0/double_float(pow)));
        !            20:     end if;
        !            21:     if REAL_PART(nt) >= REAL_PART(target)
        !            22:       or else abs( REAL_PART(nt) - REAL_PART(target) ) <= tol
        !            23:      then hh := REAL_PART(target) - REAL_PART(t);
        !            24:           t := target;
        !            25:      else hh := h;
        !            26:           t := nt;
        !            27:     end if;
        !            28:   end Real_Predictor;
        !            29:
        !            30:   procedure Complex_Predictor
        !            31:                ( t : in out Complex_Number; target : in Complex_Number;
        !            32:                  h,tol : in double_float; hh : out double_float;
        !            33:                  distance : in double_float; trial : in natural ) is
        !            34:
        !            35:     nt,target_direction,step : Complex_Number;
        !            36:     dre,dim,d,x,y,alfa,absnt : double_float;
        !            37:     tr3 : natural range 0..2;
        !            38:
        !            39:   begin
        !            40:     target_direction := target - t;
        !            41:     d := AbsVal(target_direction);
        !            42:     if d < tol
        !            43:      then nt := target - Create(distance);
        !            44:           hh := AbsVal(nt - t);
        !            45:      else tr3 := trial mod 3;
        !            46:          case tr3 is
        !            47:            when 0 => target_direction := target_direction / Create(d);
        !            48:                       if (d - h) > distance
        !            49:                        then step := Create(h) * target_direction;
        !            50:                        else step := (d - distance) * target_direction;
        !            51:                       end if;
        !            52:                       nt := t + step;
        !            53:            when 1 => dre := REAL_PART(target_direction);
        !            54:                       dim := IMAG_PART(target_direction);
        !            55:                       alfa := ARCTAN(dim/dre);
        !            56:                       x := h * COS(alfa + PI/4.0);
        !            57:                       y := h * SIN(alfa + PI/4.0);
        !            58:                       step := Create(x,y);
        !            59:                       nt := t + step;
        !            60:                       absnt := AbsVal(nt);
        !            61:                       if (absnt > AbsVal(target))
        !            62:                          or else (AbsVal(nt - target) < distance)
        !            63:                         then step := Create(0.0,y) * Create(h);
        !            64:                              nt := t + step;
        !            65:                       end if;
        !            66:            when 2 => dre := REAL_PART(target_direction);
        !            67:                       dim := IMAG_PART(target_direction);
        !            68:                       alfa := ARCTAN(dim/dre);
        !            69:                       x := h * COS(alfa - PI/4.0);
        !            70:                       y := h * SIN(alfa - PI/4.0);
        !            71:                       step := Create(x,y);
        !            72:                       nt := t + step;
        !            73:                       absnt := AbsVal(nt);
        !            74:                       if (absnt > AbsVal(target))
        !            75:                          or else (AbsVal(nt - target) < distance)
        !            76:                         then step := Create(0.0,-y) * Create(h);
        !            77:                              nt := t + step;
        !            78:                       end if;
        !            79:           end case;
        !            80:           hh := AbsVal(step);
        !            81:     end if;
        !            82:     t := nt;
        !            83:   end Complex_Predictor;
        !            84:
        !            85:   procedure Circular_Predictor
        !            86:               ( t : in out Complex_Number; theta : in out double_float;
        !            87:                 t0_min_target,target : in Complex_Number;
        !            88:                 h : in double_float ) is
        !            89:
        !            90:     e_i_theta : Complex_Number;
        !            91:
        !            92:   begin
        !            93:     theta := theta + h;
        !            94:     e_i_theta := Create(COS(theta),SIN(theta));
        !            95:     t := target + t0_min_target * e_i_theta;
        !            96:   end Circular_Predictor;
        !            97:
        !            98:   procedure Geometric_Predictor
        !            99:               ( t : in out Complex_Number; target : in Complex_Number;
        !           100:                 h,tol : in double_float ) is
        !           101:
        !           102:     nt : Complex_Number;
        !           103:
        !           104:   begin
        !           105:     nt := target - Create(h)*(target - t);
        !           106:     if abs( REAL_PART(nt) - REAL_PART(target) ) <= tol
        !           107:      then t := target;
        !           108:      else t := nt;
        !           109:     end if;
        !           110:   end Geometric_Predictor;
        !           111:
        !           112: -- PREDICTORS FOR x :
        !           113:
        !           114:   procedure Secant_Predictor
        !           115:               ( x : in out Solution_Array; prev_x : in Solution_Array;
        !           116:                 fac : in Complex_Number; dist_x : in double_float ) is
        !           117:
        !           118:     j : natural;
        !           119:     xx : Solution_Array(x'range);
        !           120:
        !           121:   begin
        !           122:     Copy(x,xx);
        !           123:     for i in x'range loop
        !           124:       x(i).v := x(i).v + fac * ( x(i).v - prev_x(i).v );
        !           125:       j := xx'first;
        !           126:       Equals(xx,x(i).v,i,dist_x,j);
        !           127:       if j /= i
        !           128:        then Copy(xx,x);
        !           129:             exit;
        !           130:       end if;
        !           131:     end loop;
        !           132:     Clear(xx);
        !           133:   end Secant_Predictor;
        !           134:
        !           135: -- PREDICTORS FOR t AND x :
        !           136:
        !           137:   procedure Secant_Single_Real_Predictor
        !           138:                ( x : in out Vector; prev_x : in Vector;
        !           139:                  t : in out Complex_Number; prev_t,target : in Complex_Number;
        !           140:                  h,tol : in double_float; pow : in positive := 1 ) is
        !           141:
        !           142:     hh,tmp : double_float;
        !           143:     factor : Complex_Number;
        !           144:
        !           145:   begin
        !           146:     tmp := AbsVal(t - prev_t);
        !           147:     Real_Predictor(t,target,h,tol,pow,hh);
        !           148:     if tmp > tol
        !           149:      then factor := Create(hh/tmp);
        !           150:           x := x + factor * ( x - prev_x );
        !           151:     end if;
        !           152:   end Secant_Single_Real_Predictor;
        !           153:
        !           154:   procedure Secant_Multiple_Real_Predictor
        !           155:                ( x : in out Solution_Array; prev_x : in Solution_Array;
        !           156:                  t : in out Complex_Number; prev_t,target : in Complex_Number;
        !           157:                  h,tol,dist_x : in double_float; pow : in positive := 1 ) is
        !           158:
        !           159:     hh,tmp : double_float;
        !           160:     factor : Complex_Number;
        !           161:
        !           162:   begin
        !           163:     tmp := AbsVal(t - prev_t);
        !           164:     Real_Predictor(t,target,h,tol,pow,hh);
        !           165:     if tmp > tol
        !           166:      then factor := Create(hh/tmp);
        !           167:           Secant_Predictor(x,prev_x,factor,dist_x);
        !           168:     end if;
        !           169:     for k in x'range loop
        !           170:       x(k).t := t;
        !           171:     end loop;
        !           172:   end Secant_Multiple_Real_Predictor;
        !           173:
        !           174:   procedure Secant_Single_Complex_Predictor
        !           175:                ( x : in out Vector; prev_x : in Vector;
        !           176:                  t : in out Complex_Number; prev_t,target : in Complex_Number;
        !           177:                  h,tol,dist_t : in double_float; trial : in natural ) is
        !           178:
        !           179:     hh,tmp : double_float;
        !           180:     factor : Complex_Number;
        !           181:
        !           182:   begin
        !           183:     tmp := AbsVal(t - prev_t);
        !           184:     Complex_Predictor(t,target,h,tol,hh,dist_t,trial);
        !           185:     if tmp > tol
        !           186:      then factor := Create(hh/tmp);
        !           187:           x := x + factor * ( x - prev_x );
        !           188:     end if;
        !           189:   end Secant_Single_Complex_Predictor;
        !           190:
        !           191:   procedure Secant_Multiple_Complex_Predictor
        !           192:                ( x : in out Solution_Array; prev_x : in Solution_Array;
        !           193:                  t : in out Complex_Number; prev_t,target : in Complex_Number;
        !           194:                  h,tol,dist_x,dist_t : in double_float; trial : in natural ) is
        !           195:
        !           196:     hh,tmp : double_float;
        !           197:     factor : Complex_Number;
        !           198:
        !           199:   begin
        !           200:     tmp := AbsVal(t - prev_t);
        !           201:     Complex_Predictor(t,target,h,tol,hh,dist_t,trial);
        !           202:     if tmp > tol
        !           203:      then factor := Create(hh/tmp);
        !           204:           Secant_Predictor(x,prev_x,factor,dist_x);
        !           205:     end if;
        !           206:     for k in x'range loop
        !           207:       x(k).t := t;
        !           208:     end loop;
        !           209:   end Secant_Multiple_Complex_Predictor;
        !           210:
        !           211:   procedure Secant_Circular_Predictor
        !           212:                ( x : in out Vector; prev_x : in Vector;
        !           213:                  t : in out Complex_Number; theta : in out double_float;
        !           214:                  prev_t,t0_min_target,target : in Complex_Number;
        !           215:                  h,tol : in double_float ) is
        !           216:
        !           217:     factor : Complex_Number;
        !           218:     tmp : double_float := AbsVal(t-prev_t);
        !           219:
        !           220:   begin
        !           221:     if tmp <= tol
        !           222:      then Circular_Predictor(t,theta,t0_min_target,target,h);
        !           223:      else factor := Create(h/tmp);
        !           224:           Circular_Predictor(t,theta,t0_min_target,target,h);
        !           225:           x := x + factor * ( x - prev_x );
        !           226:     end if;
        !           227:   end Secant_Circular_Predictor;
        !           228:
        !           229:   procedure Secant_Geometric_Predictor
        !           230:                ( x : in out Vector; prev_x : in Vector;
        !           231:                  t : in out Complex_Number; prev_t,target : in Complex_Number;
        !           232:                  h,tol : in double_float ) is
        !           233:
        !           234:     dist_prev,dist : double_float;
        !           235:     factor,tmp : Complex_Number;
        !           236:
        !           237:   begin
        !           238:     dist_prev := AbsVal(t - prev_t);     -- old stepsize
        !           239:     tmp := t;
        !           240:     Geometric_Predictor(t,target,h,tol);
        !           241:     dist := AbsVal(t - tmp);             -- new stepsize
        !           242:     if dist_prev > tol
        !           243:      then factor := Create(dist/dist_prev);
        !           244:           x := x + factor * ( x - prev_x );
        !           245:     end if;
        !           246:   end Secant_Geometric_Predictor;
        !           247:
        !           248:   procedure Tangent_Single_Real_Predictor
        !           249:                ( x : in out Vector; t : in out Complex_Number;
        !           250:                  target : in Complex_Number; h,tol : in double_float;
        !           251:                  pow : in positive := 1 ) is
        !           252:
        !           253:     n : natural := x'last;
        !           254:     info : integer;
        !           255:     norm_tan,hh : double_float;
        !           256:     rhs : Vector(x'range);
        !           257:     j : Matrix(1..n,1..n);
        !           258:     ipvt : Standard_Natural_Vectors.Vector(1..n);
        !           259:     prev_t : Complex_Number := t;
        !           260:
        !           261:   begin
        !           262:     Real_Predictor(t,target,h,tol,pow,hh);
        !           263:     j := dH(x,prev_t);
        !           264:     lufac(j,n,ipvt,info);
        !           265:     if info = 0
        !           266:      then rhs := dH(x,prev_t);
        !           267:           Min(rhs);
        !           268:           lusolve(j,n,ipvt,rhs);
        !           269:           norm_tan := Norm(rhs);
        !           270:           if norm_tan > tol
        !           271:            then hh := hh / norm_tan;
        !           272:                 Mul(rhs,Create(hh));
        !           273:                 Add(x,rhs);
        !           274:           end if;
        !           275:     end if;
        !           276:   end Tangent_Single_Real_Predictor;
        !           277:
        !           278:   procedure Tangent_Multiple_Real_Predictor
        !           279:                ( x : in out Solution_Array; t : in out Complex_Number;
        !           280:                  target : in Complex_Number; h,tol,dist_x : in double_float;
        !           281:                  nsys : in out natural; pow : in positive := 1 ) is
        !           282:
        !           283:     n : natural := x(x'first).n;
        !           284:     norm_tan,hh : double_float;
        !           285:     rhs : Vector(1..n);
        !           286:     info : integer;
        !           287:     j : Matrix(1..n,1..n);
        !           288:     ipvt : Standard_Natural_Vectors.Vector(1..n);
        !           289:     xx : Solution_Array(x'range);
        !           290:     jj : natural;
        !           291:     prev_t : Complex_Number := t;
        !           292:
        !           293:   begin
        !           294:     Real_Predictor(t,target,h,tol,pow,hh);
        !           295:     Copy(x,xx);
        !           296:     for i in x'range loop
        !           297:       j := dH(x(i).v,prev_t);
        !           298:       lufac(j,n,ipvt,info);
        !           299:       if info = 0
        !           300:        then rhs := dH(x(i).v,prev_t);
        !           301:             Min(rhs);
        !           302:             lusolve(j,n,ipvt,rhs);
        !           303:             nsys := nsys + 1;
        !           304:             norm_tan := Norm(rhs);
        !           305:             if norm_tan > tol
        !           306:              then hh := hh / norm_tan;
        !           307:                   Mul(rhs,Create(hh));
        !           308:                   Add(x(i).v,rhs);
        !           309:             end if;
        !           310:             jj := xx'first;
        !           311:             Equals(xx,x(i).v,i,dist_x,jj);
        !           312:             if jj /= i
        !           313:              then Copy(xx,x); exit;
        !           314:             end if;
        !           315:        else Copy(xx,x); exit;
        !           316:       end if;
        !           317:     end loop;
        !           318:     Clear(xx);
        !           319:     for k in x'range loop
        !           320:       x(k).t := t;
        !           321:     end loop;
        !           322:   end Tangent_Multiple_Real_Predictor;
        !           323:
        !           324:   procedure Tangent_Single_Complex_Predictor
        !           325:                ( x : in out Vector; t : in out Complex_Number;
        !           326:                  target : in Complex_Number;
        !           327:                  h,tol,dist_t : in double_float; trial : in natural) is
        !           328:
        !           329:     n : natural := x'last;
        !           330:     info : integer;
        !           331:     norm_tan,hh : double_float;
        !           332:     rhs : Vector(x'range);
        !           333:     j : Matrix(1..n,1..n);
        !           334:     ipvt : Standard_Natural_Vectors.Vector(1..n);
        !           335:     prev_t : Complex_Number := t;
        !           336:
        !           337:   begin
        !           338:     Complex_Predictor(t,target,h,tol,hh,dist_t,trial);
        !           339:     j := dH(x,prev_t);
        !           340:     lufac(j,n,ipvt,info);
        !           341:     if info = 0
        !           342:      then rhs := dH(x,prev_t);
        !           343:           Min(rhs);
        !           344:           lusolve(j,n,ipvt,rhs);
        !           345:           norm_tan := Norm(rhs);
        !           346:           if norm_tan > tol
        !           347:            then hh := hh / norm_tan;
        !           348:                 Mul(rhs,Create(hh));
        !           349:                 Add(x,rhs);
        !           350:           end if;
        !           351:     end if;
        !           352:   end Tangent_Single_Complex_Predictor;
        !           353:
        !           354:   procedure Tangent_Multiple_Complex_Predictor
        !           355:                ( x : in out Solution_Array; t : in out Complex_Number;
        !           356:                  target : in Complex_Number;
        !           357:                  h,tol,dist_x,dist_t : in double_float;
        !           358:                  trial : in natural; nsys : in out natural) is
        !           359:
        !           360:     n : natural := x(x'first).n;
        !           361:     norm_tan,hh : double_float;
        !           362:     rhs : Vector(1..n);
        !           363:     info : integer;
        !           364:     j : Matrix(1..n,1..n);
        !           365:     ipvt : Standard_Natural_Vectors.Vector(1..n);
        !           366:     xx : Solution_Array(x'range);
        !           367:     jj : natural;
        !           368:     prev_t : Complex_Number := t;
        !           369:
        !           370:   begin
        !           371:     Complex_Predictor(t,target,h,tol,hh,dist_t,trial);
        !           372:     Copy(x,xx);
        !           373:     for i in x'range loop
        !           374:       j := dH(x(i).v,prev_t);
        !           375:       lufac(j,n,ipvt,info);
        !           376:       if info = 0
        !           377:        then rhs := dH(x(i).v,prev_t);
        !           378:             Min(rhs);
        !           379:             lusolve(j,n,ipvt,rhs);
        !           380:             nsys := nsys + 1;
        !           381:             norm_tan := Norm(rhs);
        !           382:             if norm_tan > tol
        !           383:              then hh := hh / norm_tan;
        !           384:                   Mul(rhs,Create(hh));
        !           385:                   Add(x(i).v,rhs);
        !           386:             end if;
        !           387:             jj := xx'first;
        !           388:             Equals(xx,x(i).v,i,dist_x,jj);
        !           389:             if jj /= i
        !           390:              then Copy(xx,x); exit;
        !           391:             end if;
        !           392:        else Copy(xx,x); exit;
        !           393:       end if;
        !           394:     end loop;
        !           395:     Clear(xx);
        !           396:     for k in x'range loop
        !           397:       x(k).t := t;
        !           398:     end loop;
        !           399:   end Tangent_Multiple_Complex_Predictor;
        !           400:
        !           401:   procedure Tangent_Circular_Predictor
        !           402:               ( x : in out Vector; t : in out Complex_Number;
        !           403:                 theta : in out double_float;
        !           404:                 t0_min_target,target : in Complex_Number;
        !           405:                 h,tol : in double_float ) is
        !           406:
        !           407:     n : natural := x'last;
        !           408:     info : integer;
        !           409:     norm_tan : double_float;
        !           410:     rhs : Vector(x'range);
        !           411:     j : Matrix(1..n,1..n);
        !           412:     ipvt : Standard_Natural_Vectors.Vector(1..n);
        !           413:
        !           414:   begin
        !           415:     lufac(j,n,ipvt,info);
        !           416:     if info = 0
        !           417:      then rhs := dH(x,t);
        !           418:           Min(rhs);
        !           419:           lusolve(j,n,ipvt,rhs);
        !           420:     end if;
        !           421:     Circular_Predictor(t,theta,t0_min_target,target,h);
        !           422:     if info = 0
        !           423:      then norm_tan := Norm(rhs);
        !           424:           if norm_tan > tol
        !           425:            then Mul(rhs,Create(h/norm_tan));
        !           426:                 Add(x,rhs);
        !           427:           end if;
        !           428:     end if;
        !           429:   end Tangent_Circular_Predictor;
        !           430:
        !           431:   procedure Tangent_Geometric_Predictor
        !           432:                ( x : in out Vector; t : in out Complex_Number;
        !           433:                  target : in Complex_Number; h,tol : in double_float ) is
        !           434:
        !           435:     n : natural := x'last;
        !           436:     info : integer;
        !           437:     norm_tan,step : double_float;
        !           438:     rhs : Vector(x'range);
        !           439:     j : Matrix(1..n,1..n);
        !           440:     ipvt : Standard_Natural_Vectors.Vector(1..n);
        !           441:     prev_t : Complex_Number := t;
        !           442:
        !           443:   begin
        !           444:     Geometric_Predictor(t,target,h,tol);
        !           445:     j := dH(x,prev_t);
        !           446:     lufac(j,n,ipvt,info);
        !           447:     if info = 0
        !           448:      then rhs := dH(x,prev_t);
        !           449:           Min(rhs);
        !           450:           lusolve(j,n,ipvt,rhs);
        !           451:           norm_tan := Norm(rhs);
        !           452:           if norm_tan > tol
        !           453:            then step := AbsVal(t-prev_t) / norm_tan;
        !           454:                 Mul(rhs,Create(step));
        !           455:                 Add(x,rhs);
        !           456:           end if;
        !           457:     end if;
        !           458:   end Tangent_Geometric_Predictor;
        !           459:
        !           460:   function Hermite ( t0,t1,t,x0,x1,v0,v1 : Complex_Number )
        !           461:                    return Complex_Number is
        !           462:
        !           463:   -- DESCRIPTION :
        !           464:   --   Returns the value of the third degree interpolating polynomial x(t),
        !           465:   --   such that x(t0) = x0, x(t1) = x1, x'(t0) = v0 and x'(t1) = v1.
        !           466:
        !           467:   -- REQUIRED : t0 /= t1.
        !           468:
        !           469:   -- IMPLEMENTATION :
        !           470:   --   x(t) = a3*t^3 + a2*t^2 + a1*t + a0,
        !           471:   --   The four interpolation conditions lead to a linear system in
        !           472:   --   the coefficients of x(t).  This system is first solved explicitly
        !           473:   --   and then the polynomial x(t) is evaluated.
        !           474:
        !           475:     a0,a1,a2,a3,t10,v10 : Complex_Number;
        !           476:
        !           477:   begin
        !           478:     t10 := t1 - t0;
        !           479:     v10 := (x1 - x0)/t10;
        !           480:     a3 := (v1 + v0 - Create(2.0)*v10)/(t10**2);
        !           481:     a2 := (v10 - v0 - (t1**2 + t1*t0 - Create(2.0)*t0**2)*a3)/t10;
        !           482:     a1 := v0 - (Create(3.0)*a3*t0 + Create(2.0)*a2)*t0;
        !           483:     a0 := x0 - ((a3*t0 + a2)*t0 + a1)*t0;
        !           484:     return (((a3*t + a2)*t + a1)*t + a0);
        !           485:   end Hermite;
        !           486:
        !           487:   function Hermite ( t0,t1,t : Complex_Number; x0,x1,v0,v1 : Vector )
        !           488:                    return Vector is
        !           489:
        !           490:   -- DESCRIPTION :
        !           491:   --   Returns the value of the third degree interpolating polynomial x(t),
        !           492:   --   such that x(t0) = x0, x(t1) = x1, x'(t0) = v0 and x'(t1) = v1,
        !           493:   --   for every component.
        !           494:
        !           495:   -- REQUIRED : t0 /= t1.
        !           496:
        !           497:     res : Vector(x0'range);
        !           498:
        !           499:   begin
        !           500:     for i in res'range loop
        !           501:       res(i) := Hermite(t0,t1,t,x0(i),x1(i),v0(i),v1(i));
        !           502:     end loop;
        !           503:     return res;
        !           504:   end Hermite;
        !           505:
        !           506:   procedure Hermite_Single_Real_Predictor
        !           507:                 ( x : in out Vector; prev_x : in Vector;
        !           508:                   t : in out Complex_Number; prev_t,target : in Complex_Number;
        !           509:                   v : in out Vector; prev_v : in Vector;
        !           510:                   h,tol : in double_float; pow : in positive := 1 ) is
        !           511:
        !           512:     n : natural := x'last;
        !           513:     info : integer;
        !           514:     hh : double_float;
        !           515:     j : Matrix(1..n,1..n);
        !           516:     ipvt : Standard_Natural_Vectors.Vector(1..n);
        !           517:     t1 : Complex_Number := t;
        !           518:
        !           519:   begin
        !           520:     Real_Predictor(t,target,h,tol,pow,hh);
        !           521:     j := dH(x,t1);
        !           522:     lufac(j,n,ipvt,info);
        !           523:     if info = 0
        !           524:      then v := dH(x,t1);
        !           525:           Min(v);
        !           526:           lusolve(j,n,ipvt,v);
        !           527:           if AbsVal(prev_t - t1) > tol
        !           528:            then x := Hermite(prev_t,t1,t,prev_x,x,prev_v,v);
        !           529:           end if;
        !           530:     end if;
        !           531:   end Hermite_Single_Real_Predictor;
        !           532:
        !           533: end Predictors;

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>