/* Dormand Prince in Javascript mascherato da doc HTML

LIBRERIA DORMAND PRINCE Javascript - 6 giugno 2014.

Con estensione HTML posso ottenere persino scritte rosse! In rete:
http://www.elegio.it/calcolatrice/libreria-dormand-prince-v2.js.html
http://www.elegio.it/calcolatrice/nuova-dormand-prince.html

Come usare la funzione odedopri

La odedopri(fder,x0,vy0,x1,vcosta,vpeso,tol,maxiter) è la funzione fondamentale che usa i seguenti argomenti:
  1. fder(x,vy,vc) ossia la function da usare nel RungeKutta e che va realizzata con dati di ingresso e uscita di questo tipo.
    • Il primo argomento di fder è la variabile indipendente.
    • Il secondo argomento di fder è il vettore delle variabili dipendenti che deve essere lungo nvariabili+1 perché l'elemento iniziale, il numero 0, non viene mai usato in Javascript.
    • Il terzo argomento di fder è il vettore delle costanti usate per calcolare le derivate prime delle variabili dipendenti; queste costanti possono essere quante servono ma non vanno mai cambiate ma solo usate.
    Il risultato di questa funzione deve essere un vettore di lunghezza maggiore di uno delle variabili dipendenti ossia nvariabili+1 come il vettore vy, in cui l'elemento iniziale ossia il numero 0, non è mai usato mentre gli altri sono le derivate prime delle variabili dipendenti.
  2. x0 == Valore iniziale della variabile indipendente.
  3. vy0 == Valore iniziale del vettore delle variabili dipendenti.
  4. x1 == Valore finale desiderato della variabile indipendente.
  5. vcosta == Costanti usate per calcolare le derivate prime delle variabili dipendenti che all'inizio valgono vy0.
  6. vpeso == Vettore usato per equilibrare l'importanza degli errori del calcolo. Spesso l'errore di una qualche variabile ha importanza molto diversa dall'errore di una qualche altra variabile.
  7. tol == parametro usato per limitare l'errore. Più è piccolo e maggiore è la precisione ossia minore la tolleranza dell'errore totale ottenuto come somma degli errori delle varie variabili pesati sul peso della loro importanza.
  8. maxiter == numero massimo di iterazioni ammesse.
  1. LA FUNZIONE PRODUCE QUESTO VETTORE RISULTATO: [0,x,vy,itfatte]
    • Il primo elemento, in Javascript l'elemento 0, non viene mai usato
    • x rappresenta il valore finale della variabile indipendente per cui, se tutto è andato bene, deve valere x1.
    • vy rappresenta il vettore delle variabili dipendenti finali.
    • ifatte rappresenta il numero di iterazioni fatte effettivamente.
*/ 
var libodedopriversione=["Giorno giuliano : ",gregorianoingg(2014,06,05)];
//
function odedopri(fder,x0,y0,x1,costa,peso,tol,maxiter){
   var ha21,ha31,ha32,ha41,ha42,ha43,ha51,ha52,ha53,ha54,
       ha61,ha62,ha63,ha64,ha65,ha71,ha73,ha74,ha75,ha76;
   var e1,e3,e4,e5,e6,e7;
   var i,j,ifa,x,ny,h,hmax,hmin,verrore,erromax;
   var y=[0],z=[0],k1=[0],k2=[0],k3=[0],k4=[0],k5=[0],k6=[0],k7=[0];
   x=x0;
   ny=y0.length;
   // alert("ny = "+ny);
   for(j=1;ny>j;j++)y[j]=y0[j]; 
   h=10*(x1-x0)/(maxiter*171362822400);
   hmax=h;
   hmin=h/100;
   erromax=0;
   amen=false;
   e1=211228479;
   e3=-728766720;
   e4=6336854370;
   e5=-8716163841;
   e6=7180918272;
   e7=-4284070560;
   k1=fder(x,y,costa);
   //
   // alert("Stampo k1 \n"+k1);
   //
   for(i=1;maxiter>=i;i++){
       ifa=i;
       ha21=34272564480*h;
       for(j=1;ny>j;j++)z[j]=y[j]+ha21*k1[j]; 
       k2=fder(x+34272564480*h,z,costa);
       ha31=12852211680*h;
       ha32=38556635040*h;
       for(j=1;ny>j;j++)z[j]=y[j]+ha31*k1[j]+ha32*k2[j]; 
       k3=fder(x+51408846720*h,z,costa);
       ha41=167554759680*h;
       ha42=-639754536960*h;
       ha43=609290035200*h;
       for(j=1;ny>j;j++)z[j]=y[j]+ha41*k1[j]+ha42*k2[j]+
          ha43*k3[j]; 
       k4=fder(x+137090257920*h,z,costa);
       ha51=505965644800*h;
       ha52=-1987087872000*h;
       ha53=1683278643200*h;
       ha54=-49833907200*h;
       for(j=1;ny>j;j++)z[j]=y[j]+ha51*k1[j]+ha52*k2[j]+
          ha53*k3[j]+ha54*k4[j]; 
       k5=fder(x+152322508800*h,z,costa);
       ha61=487745760600*h;
       ha62=-1843448544000*h;
       ha63=1526229734400*h;
       ha64=47708967600*h;
       ha65=-46873096200*h;
       hc6=171362822400*h;
       for(j=1;ny>j;j++)z[j]=y[j]+ha61*k1[j]+ha62*k2[j]+
          ha63*k3[j]+ha64*k4[j]+ha65*k5[j]; 
       k6=fder(x+hc6,z,costa);
       ha71=15619007250*h;
       ha73=76982400000*h;
       ha74=111564337500*h;
       ha75=-55243291950*h;
       ha76=22440369600*h;
       for(j=1;ny>j;j++)z[j]=y[j]+ha71*k1[j]+
          ha73*k3[j]+ha74*k4[j]+ha75*k5[j]+ha76*k6[j]; 
       k7=fder(x+171362822400*h,z,costa);
       //
       erromax=0;
       for(j=1; ny>j; j++){verrore=peso[j]*
              Math.abs(e1*k1[j]+e3*k3[j]+e4*k4[j]+e5*k5[j]+
              e6*k6[j]+e7*k7[j]);
          if(verrore>erromax)erromax=verrore;}
       //
       if(tol>erromax/171362822400){avanti=true;}
       else{ 
           if(hc6>hmin){h=h/2;avanti=false;} 
           else { avanti=true; }
           amen=false;}
       //
       if(avanti){
          x=x+hc6;
          for(j=1; ny>j; j++){
             y[j]=y[j]+ha71*k1[j]+ha73*k3[j]+ha74*k4[j]+
                  ha75*k5[j]+ha76*k6[j];
             k1[j]=k7[j]};
          if(amen){break};
          if(hmax>h)h=1.05*h;
          }
       if(x+h*171362822400>x1){ 
          h=(x1-x)/171362822400;amen=true};
      //
      };
   //
   //  amen vale true se ha fatto tutto, altrimenti false.
   //  ifa indica il numero di iterazioni fatte realmente.
   //
   return [0,amen,x,y,ifa];
   }
//
// __________________________________________________________
//
//  CASI PROVA LIBRERIA DORMAND PRINCE
//
//  Ogni caso e' basato su due funzioni. La funzione da integrare
//  e la funzione che fa l'inizializzazione dei dati del calcolo.
//
//  Le seguenti sono le variabili d'ambiente utilizzate:
//
//
var tol=1.0e-13,maxiter=250;
var x_0,x_1,y_0,costa,peso;
//
//
// Primo caso prova, elementare...
//
//
function primafder(x,y,c){
   var rr;
   rr=Math.exp(2*x)/2;
   return [0,1,rr+1.5*y[2]];
   }
//
function ini_fder1(){
   x_0=0;
   x_1=1;
   y_0=[0,0,1];
   costa=[0,1];
   peso=[0,1,1];
   tol=1.0e-13;    
   maxiter=250;
   return [0,x_0,y_0,x_1,costa,peso,tol,maxiter]
   }
//
//
// Secondo caso prova leggermente piu' complicato.
//
//
function secondafder(x,v,c){
   var y,z;
   y=v[1];
   z=v[2];
   return [0,z/2,-2*y];
   }
//
function ini_fder2(){
   x_0=0;
   x_1=1.5*Math.PI;
   y_0=[0,0,2];
   costa=[0,1];
   peso=[0,1,1];
   tol=1.0e-13;    
   maxiter=2000;
   return [0,x_0,y_0,x_1,costa,peso,tol,maxiter]
   }
//
//
// Terzo caso prova: moto piano ( bidimensionale ) di un
// asteroide attorno al Sole. 
//
//
function terzafder(t,v,c){
   var x,y,vx,vy,mu,rq,rr,den,x_,y_,vx_,vy_;
   x=v[1];
   y=v[2];
   vx=v[3];
   vy=v[4];
   mu=c[1];
   x_=vx;
   y_=vy;
   rq=x*x+y*y;
   rr=Math.sqrt(rq);
   den=1/(rr*rq);
   vx_=-mu*x*den;
   vy_=-mu*y*den;
   // 
   // Il risultato e' il vettore delle quattro variabili ossia:
   // la derivata della posizione in ascissa, 
   // la derivata della posizione in ordinata,
   // la derivata della velocita' in ascissa,
   // la derivata della velocita' in ordinata.
   //
   return [0,x_,y_,vx_,vy_];
   }
//
function ini_fder3(){
   // velocita' media, al perielio, all'afelio, eccentricita'... 
   var vm,vp,va,ec;
   costa=[0,1.327581e20,149.61e9,30500.0];
   vm=Math.sqrt(costa[1]/costa[2]);
   if(costa[3]>vm){vp=costa[3];va=vm*vm/vp;}
   else {va=costa[3];vp=vm*vm/va};
   ec=(vp-va)/(vp+va);
   x_0=0;
   x_1=2*Math.PI*costa[2]/vm;
   y_0=[0,costa[2]*(1-ec),0,0,vp];
   peso=[0,1.0e-9,1.0e-9,1.0e-4,1.0e-4];
   tol=5.0e-14;    
   maxiter=500;
   return [0,x_0,y_0,x_1,costa,peso,tol,maxiter];
   }
//
//_________________________________________________________________
//
//  Problema di tre corpi nel piano ( Terra e Luna 
//     attorno al Sole immobile )
//  xt e yt sono l'ascissa e l'ordinata della Terra,
//  xl e yl sono l'ascissa e l'ordinata della Luna.
//  x sarebbe il tempo che pero' non interviene esplicitamente
//  nel calcolo delle derivate prime.
//  vxt e vyt sono la velocita' della Terra in ascissa e in ordinata.
//  vxl e vyl sono la velocita' della Luna in ascissa e in ordinata.
//  dunque le variabili sono in totale 8 e di queste la funzione
//  deve produrre le loro derivate prime.
//
//  Nel caso delle posizioni ossia le prime 4 variabili, le derivate 
//  prime sono ovviamente le velocita'.
//  Nel caso delle velocita' ossia le variabili dalla quinta alla 
//  ottava, le derivate prime sono ovviamente le forze. 
//
//  Qui tratto consecutivamente le posizioni e poi le velocita'
//  ma sarebbe stato meglio raggruppare tutte le variabili
//  di uno stesso oggetto... come ho fatto nel successivo
//  caso completamente generale.
//
//
function quartafder(x,v,c){
   var mu,ts,xt,yt,vxt,vyt,rqt,rrt,dent,xt_,yt_,vxt_,vyt_;
   var dentl,denlt,ls,xl,yl,vxl,vyl,rql,rrl,denl,xl_yl_,vxl_vyl_;
   //
   // Ricopia il vettore delle coordinate solo per rendere 
   // piu' leggibile questa funzione.
   //
   xt=v[1];
   yt=v[2];
   xl=v[3];
   yl=v[4];
   vxt=v[5];
   vyt=v[6];
   vxl=v[7];
   vyl=v[8];
   //
   // mu e' la azione gravitazionale del Sole ossia la sua massa per G 
   //      ossia la costante di gravitazione universale.
   // ts e' il rapporto tra la massa della Terra e  quella del Sole
   // ls e' il rapporto tra la massa della Luna e quella del Sole...
   //
   mu=c[1];
   ts=c[2];
   ls=c[3];
   //
   // Ovviamente le derivate prime delle velocita' della Terra e della
   // Luna sono le velocita' ( bidimensionali, in ascissa e ordinata ) 
   //
   xt_=vxt;
   yt_=vyt;
   xl_=vxl;
   yl_=vyl;
   //
   // rqt e' il quadrato della distanza della Terra dal Sole.
   //
   rqt=xt*xt+yt*yt;
   //
   // rrt e' la distanza della Terra dal Sole.
   //
   rrt=Math.sqrt(rqt);
   //
   // l'inverso del cubo della distanza tra la Terra e in Sole.
   //
   dent=1/(rrt*rqt);
   //
   // rql e' il quadrato della distanza della Luna dal Sole.
   //
   rql=xl*xl+yl*yl;
   //
   // rrl e' la distanza della Luna dal Sole.
   //
   rrl=Math.sqrt(rql);
   //
   // l'inverso del cubo della distanza tra la Luna e il Sole.
   //
   denl=1/(rrl*rql);
   //
   // rqtl e' il quadrato della distanza della Luna dalla Terra.
   //
   rqtl=(xt-xl)*(xt-xl)+(yt-yl)*(yt-yl);
   //
   // rrtl e' la distanza della Luna dalla Terra.
   //
   rrtl=Math.sqrt(rqtl);
   //
   // per velocizzare i calcoli precalcolo queste due quantita'
   //
   dentl=ls/(rqtl*rrtl);
   denlt=ts/(rqtl*rrtl);
   //
   // le forze sulla Terra in ascissa ed in ordinata. Per
   // ottenere una forza attrattiva la forza deve avere il
   // segno meno. 
   //
   vxt_=-mu*(xt*dent+(xt-xl)*dentl);
   vyt_=-mu*(yt*dent+(yt-yl)*dentl);
   //
   // le forze sulla Luna in ascissa ed in ordinata
   //
   vxl_=-mu*(xl*denl+(xl-xt)*denlt);
   vyl_=-mu*(yl*denl+(yl-yt)*denlt);
   return [0,xt_,yt_,xl_,yl_,vxt_,vyt_,vxl_,vyl_];
   }
// _____________________________________________________________
//
// Produce un vettore di dati di questo quarto test ossia:
// 1== L'istante di tempo assunto come iniziale
// 2== Il vettore delle condizioni iniziali ossia le posizioni
//     delle particelle e le velocita' delle particelle.
// 3== L'istante di tempo che bisogna raggiungere.
// 4== Le costanti da usare per calcolare le forze ossia 
//     le accelerazioni.
// 5== Il vettore di equilibramento delle tolleranze degli errori.
// 6== Il parametro di controllo dell'errore, piccolissimo 
//     se molto preciso.
// 7== Il numero massimo delle iterazioni ammesse per fare 
//     evolvere il sistema fino alla fine.  
//
function ini_fder4(){
   var vm,vp,va,ec;
   //
   // Le costanti usate sono:
   // 1== la costante gravitazionale solare ossia
   //     la massa del sole per la G ossia costante di 
   //     gravitazione universale.
   // 2== Il rapporto tra la massa della Terra e la massa del Sole.
   // 3== Il rapporto tra la massa della Luna e la massa del Sole
   //     e la massa della Luna e' circa un ottantesimo della massa
   //     della terra per cui uso questo dato...
   // 4== La distanza iniziale della Terra dal Sole.
   // 5== La velocita' in metri al secondo della Terra.
   //
   costa=[0,1.327581e20, 1/333000.1, 1/(333000.1*80), 
            149.61e9, 30500.0];
   vm=Math.sqrt(costa[1]/costa[4]);
   if(costa[5]>vm){vp=costa[5];va=vm*vm/vp;}
   else {va=costa[5];vp=vm*vm/va; };
   ec=(vp-va)/(vp+va);
   //
   // x_0 e' l'istante iniziale del transitorio. 
   //
   x_0=0;
   //
   // x_1 e' l'istante finale a cui vorrei arrivare nella simulazione.
   //
   x_1=2*Math.PI*costa[4]/vm;
   //
   // y_0 e' il vettore delle incognite: 4 posizioni e 4 velocita'.
   //
   y_0=[0,costa[4]*(1-ec),0,costa[4]*(1-ec),-360e6,0,vp,1100.0,vp];
   //
   // il vettore peso controlla la tolleranza del calcolo
   // Il peso delle posizioni deve essere molto piccolo
   // rispetto ai pesi delle velocita' perche' le
   // posizioni si misurano in miliardi di metri e le
   // velocita' si misurano in decine di migliaia di metri al secondo.
   //
   peso=[0,1e-9,1e-9,1e-9,1e-9,1e-4,1e-4,1e-4,1e-4];
   //
   // Il criterio di tolleranza piuttosto severo...
   //
   tol=0.5e-14; 
   //
   // il massimo numero delle iterazioni consentite:
   //
   maxiter=2000;
   // 
   // Ecco il vettore risultato usabile per inizializzare i calcoli.
   // Notare che tutti questi dati sono variabili globali
   // e non locali mentre il vettore risultato e' solo una raccolta
   // di queste variabili globali inizializzate da questa funzione.
   // 
   return [0,x_0,y_0,x_1,costa,peso,tol,maxiter];
   }
//
//_________________________________________________________________
//
// Sistema molticorpi tridimensionale in meccanica classica. 
// Ogni corpo ha sei dati: tre posizioni e tre velocita'.
// Se il corpo e' unico la variazione della posizione e' 
// data dalla velocita' posseduta inizialmente ma
// la variazione della velocita' e' nulla ossia il corpo
// si muove di moto rettilineo uniforme e quindi il sistema piu' 
// semplice significativo e' a due corpi... ma ovviamente 
// i corpi possono essere moltissimi...
//
// Se i corpi sono p, il vettore v deve essere lungo piu' di 6*p
// ma meno di 6*p+6 e il vettore c deve essere lungo almeno p+1
// e sono usate come masse i valori da 1 a p.
//
//
function quintafder(t,v,c){
    var n=v.length,vder=[0];
    var px,py,pz,qx,qy,qz,dq,ud,j,k;
    var p=(n-n%6)/6,jj,kk,mm,nn=6*p;
    for(j=1;nn>=j;j++)vder[j]=0;
    for(j=1;p>j;j++){
       jj=j*6;
       px=v[jj-5];
       py=v[jj-4];
       pz=v[jj-3];
       vder[jj-5]=v[jj-2];
       vder[jj-4]=v[jj-1];
       vder[jj-3]=v[jj];
       for(k=j+1;p>=k;k++){
          kk=k*6;
          qx=v[kk-5]-px;
          qy=v[kk-4]-py;
          qz=v[kk-3]-pz;
          dq=qx*qx+qy*qy+qz*qz+1.e-100;
          ud=1/(dq*Math.sqrt(dq));
          mm=c[k]*ud;
          vder[jj-2]+=mm*qx;
          vder[jj-1]+=mm*qy;
          vder[jj]  +=mm*qz;
          mm=-c[j]*ud;
          vder[kk-2]+=mm*qx;
          vder[kk-1]+=mm*qy;
          vder[kk]  +=mm*qz;
          };}
    vder[nn-5]=v[nn-2];
    vder[nn-4]=v[nn-1];
    vder[nn-3]=v[nn];
    return vder;
    }
//
//
//  Si basa sulla posizione in memoria della quintafder.
//
//  Fa in modo che la velocita' del baricentro sia nulla
//  e mostra la velocita' che aveva prima.
//  La prima volta usata ottiene le correzioni necessarie 
//  mentre le volte successive dovrebbe ottenere tre zeri 
//  o, comunque, tre valori piccolissimi, non nulli solo 
//  a causa della limitata precisione dei calcoli numerici.
//
//
function fermabaricentro(v,c){
    var mb=0,vbx=0,vby=0,vbz=0;
    var j,jj,n=v.length,p=(n-n%6)/6;
    for(j=1;p>=j;j++){
       jj=j*6;
       mb+=c[j];
       vbx+=c[j]*v[jj-2];
       vby+=c[j]*v[jj-1];
       vbz+=c[j]*v[jj];}
    vbx=-vbx/mb;
    vby=-vby/mb;
    vbz=-vbz/mb;
    for(j=1;p>=j;j++){
       jj=j*6;
       v[jj-2]+=vbx;
       v[jj-1]+=vby;
       v[jj]+=vbz;}
    return ["Barinivel",vbx,vby,vbz];
    }
//
//____________________________________________________________________
//
//PER PILOTARE I CASI PROVA DELLA LIB. DORMAND PRINCE
//
// Devono esistere le seguenti MARCHE HTML:
//
// Per il primo caso   prova : "x100", "x101", "x102".
// Per il secondo caso prova : "x200", "x201", "x202".
// Per il terzo caso   prova : "x300", "x301", "x302".
// Per il quarto caso  prova : "x400", "x401", "x402", "x403".
//
function test_casi_prova_libreria(){
    var obs,ob,p1,ris3,ris4,ris5,inforis1,inforis2;
    //
    // ======================================================
    // Prima prova.
    // Il risultato finale dovrebbe essere [1,7.38905609893065]
    //
    p1=ini_fder1();
    inforis1=[0,"var.indip.x",
       "x considerato dipendente","y","x finale","costa",
       "xpeso","ypeso","tolleranza","iterazioni massime"];
    inforis2=[0,"Bene se true, male se false","x","xdip","y",
       "iterazioni fatte" ];
    ob=document.getElementById("x100");
    ob.innerHTML="Dati di inizializzazione del primo test "+
       vedoris(p1,inforis1);
    ris3=odedopri(primafder,x_0,y_0,x_1,costa,peso,tol,maxiter);
    ob=document.getElementById("x101");
    ob.innerHTML="Avendo fatto al massimo "+maxiter+" iterazioni "+
       " non dovrebbe riuscire a trovare la soluzione "+
       vedoris(ris3,inforis2);
    if(!ris3[1])ris4=odedopri(primafder,ris3[2],ris3[3],x_1,
       costa,peso,tol,4*maxiter);
    ob=document.getElementById("x102");
    ob.innerHTML="Risultato finale avendo "+
       " quadruplicato il massimo delle iterazioni ammesse "+
        vedoris(ris4,inforis2);
    //
    // ======================================================
    //
    // Seconda prova.
    // Il risultato finale dovrebbe essere [-1,0]
    //
    p1=ini_fder2();
    inforis1=[0,"varindip.iniz.x","y","z","varindip.finale",
       "cost","ypeso","zpeso","tolleranza","maxpassi"];
    inforis2=[0,"Bene se true, male se false","xfinale",
       "yfinale","zfinale","iterazionifatte"];
    ob=document.getElementById("x200");
    ob.innerHTML="Dati di inizializzazione del secondo test "+
       vedoris(p1,inforis1);
    ris3=odedopri(secondafder,x_0,y_0,x_1,costa,peso,tol,maxiter);
    ob=document.getElementById("x201");
    ob.innerHTML="Avendo fatto al massimo "+maxiter+" iterazioni "+
       "non trova la soluzione"+
       vedoris(ris3,inforis2);
    if(!ris3[1])ris4=odedopri(secondafder,ris3[2],ris3[3],x_1,
       costa,peso,tol,4*maxiter);
    ob=document.getElementById("x202");
    ob.innerHTML="Risultato finale con il quadruplo di iterazioni"+
      " che non usa se non quando servono al criterio "+
      " di cambio ampiezza passo "+vedoris(ris4,inforis2);
    //
    // ==============================================================
    //
    // Terza prova.
    // Il risultato finale dovrebbe essere :
    //           [146079760576.14456,0,0,30500]
    //
    p1=ini_fder3();
    inforis1=[0,"t-iniziale","xaster","yaster","vxaster","vyaster",
       "t_finale","costaG*M","costa_amaggiore","costavmedia",
       "xpeso","ypeso","vxpeso","vypeso","tolleranza","Maxiterazioni"];
    inforis2=[0,"Bene se true, male se false",
       "t_finale","xfinale","yfinale","vxfinale","vyfinale",
       "iterazionifatte"];
    ob=document.getElementById("x300");
    ob.innerHTML="Dati di inizializzazione del terzo test "+
       vedoris(p1,inforis1);
    ris3=odedopri(terzafder,x_0,y_0,x_1,costa,peso,tol,maxiter);
    ob=document.getElementById("x301");
    ob.innerHTML="Avendo fatto al massimo "+maxiter+" iterazioni "+
       " in questo caso riesce al primo colpo "+
       vedoris(ris3,inforis2);
    if(!ris3[1])ris4=odedopri(terzafder,ris3[2],ris3[3],x_1,
       costa,peso,tol,maxiter)
    else ris4=ris3;
    ob=document.getElementById("x302");
    ob.innerHTML="Risultato finale "+vedoris(ris4,inforis2);
    //
    // ============================================================
    //
    // Quarta prova che commento in dettaglio...
    // Il risultato finale dovrebbe essere ???
    //
    // Innanzi tutto calcola i dati che servono per impostare i calcoli
    //
    p1=ini_fder4();
    inforis1=[0,"t-iniziale","xterra","yterra","xluna","yluna","vxterra",
       "vyterra","vxluna","vyluna","t-finale","costa G*Msole",
       "Mterrasusole","Mlunasusole","Distadalsole","Vtangen",
       "pesoxt","pesoyt","pesoxl","pesoyl","pesovxt",
       "pesovyt","pesovxl","pesovyl","tollera","Maxpassi"];
    inforis2=[0,"Bene se true ma male se false","t-finale",
       "xtfin","ytfin","xlfin","ylfin","vxtfin","vytfin","vxlfin",
       "vylfin","Iterfatte"];
    ob=document.getElementById("x400");
    ob.innerHTML="Dati di inizializzazione del quarto test "+
       vedoris(p1,inforis1);
    //
    // Poi fa un numero massimo di 20 iterazioni.
    //
    ris3=odedopri(quartafder,x_0,y_0,x_1,costa,peso,tol,20);
    ob=document.getElementById("x401");
    ob.innerHTML="Avendo fatto preliminarmente "+20+" iterazioni "+
       vedoris(ris3,inforis2);
    // 
    // Se le sole 20 iterazioni non sono bastate ad ottenere true 
    // fa realmente un altro gruppo di maxiter iterazioni, ma se sono 
    // bastate le prime 20 ad arrivare al tempo x_1, non ripete il calcolo...
    // Notare che ris3[2] e' il tempo a cui e' riuscito ad arrivare con 20 
    // iterazioni e ris3[3] e' il vettore delle condizioni iniziali.
    //
    if(!ris3[1])ris4=odedopri(quartafder,ris3[2],ris3[3],x_1,
       costa,peso,tol,maxiter)
    else ris4=ris3;
    ob=document.getElementById("x402");
    ob.innerHTML="Avendo fatto preliminarmente "+maxiter+
       " iterazioni non ce la fa "+vedoris(ris4,inforis2);
    //
    // Se non e' riuscito a raggiungere il tempo x_1 rifa' un altro 
    // blocco di maxiter iterazioni sperando che almeno questo terzo tentativo 
    // gli consenta di arrivare alla conclusione ossia al tempo x_1 desiderato.
    //
    if(!ris4[1])ris5=odedopri(quartafder,ris4[2],ris4[3],x_1,
        costa,peso,tol,maxiter)
    else ris5=ris4;
    //
    ob=document.getElementById("x403");
    ob.innerHTML="Risultato finale ottenuto ridando "+
      "i due dati, tempo e valori ottenuti "+
      "e facendo un altro blocco di iterazioni con successo "+
      vedoris(ris5,inforis2);
    //
    }
//
//_________________________________________________________________________
//
//  Una funzione di servizio per trasformare vettori 
//  e vettori di vettori in stringhe.
//
function vedoris(rr,inforr){
    // Visualizza il vettore rr
    var j,pn=[],npn,paragrafo,zz,ta=typeof([0]),
        ss=" {\u2192 ",nn=rr.length;
    if(arguments.length>2)paragrafo=arguments[2];
    else {paragrafo=[],inforr[0]=0};
    npn=paragrafo.length;
    for(j=0;npn>j;j++)pn[j]=paragrafo[j];
    pn[npn]=0;
    for(j=1;nn>j;j++){
       pn[npn]=j;
       if(typeof(rr[j])==ta) { zz=vedoris(rr[j],inforr,pn);
            ss+="[\u00ab"+pn+"\u00bb: "+zz+"] "; }
       else { zz=rr[j];
            inforr[0]=Math.min(inforr[0]+1,inforr.length-1);
            ss+="[\u00ab"+pn+":"+inforr[inforr[0]]+
                 "\u00bb: "+zz+"] ";} };
    return ss+" \u2190} ";
    }
//
//
// Funzione generica per salvare nella libreria voluta ossia lib,
// nell'elemento qui ( se e' stato creato oppure in coda )
// i dati contenuti in rr che puo' essere un dato o una lista o
// una lista contenente altre liste...
//
function salvinlib(lib,qui,rr){
   var nn=Math.min(qui,lib.length);
   lib[nn]=[];
   salvorr(lib[nn],rr);
   }
//
function salvorr(lista,rr){
    var j,mm,nn=rr.length,ta=typeof([0]);
    // Salva tutto quello che sta in rr
    for(j=0;nn>j;j++){
       mm=lista.length;
       if(typeof(rr[j])==ta){           
            lista[mm]=[];
            salvorr(lista[mm],rr[j]);}
       else lista[mm]=rr[j];
       }
    }
//
//__________________________________________________________________________
//
// Per gestire le date col calendario gregoriano prolettico ossia
// applicato ad ogni data anche precedente alla sua invenzione.
// Notare che accetta anche valori non interi dei giorni ossia
// decimi, centesimi etc. Un centesimo di giorno e' 864 secondi
// ossia 14 minuti e 24 secondi.
//
//
var LibDalGGiul="libreria del Giorno Giuliano";
function fadataLibDalGGiul(){
    var ja,jm,jg,nn,a0m1g1=gregorianoingg(0,1,1);
    var ime=[0,31,29,31,30,31,30,31,31,30,31,30,31];
    LibDalGGiul=[0];
    for(nn=1;146097>=nn;nn++)LibDalGGiul[nn]=a0m1g1;
    for(ja=0;400>ja;ja++){
       for(jm=1;13>jm;jm++){
          for(jg=1;ime[jm]>=jg;jg++){
              nn=(gregorianoingg(ja,jm,jg )-a0m1g1)%146097;
              LibDalGGiul[nn]=[ja,jm,jg];}}}
    return LibDalGGiul[146097];
    }
//
// Questa e' la funzione veramente utile nella trasformazione
// del tempo in una data comprensibile.
//
function trovadatagreg(gg){
    var gd,nn,dd,gtondo=Math.round(gg);
    if(Array.isArray(LibDalGGiul))gd=gtondo+14609700-LibDalGGiul[146097];
    else gd=gtondo+14609700-fadataLibDalGGiul();
    nn=gd%146097;
    dd=LibDalGGiul[nn];
    return [dd[0]+400*((gd-nn)/146097-100),dd[1],dd[2]+gg-gtondo];
    }
//
// Quesa funzione serve per trovare la costante da aggiungere al
// tempo iniziale di una simulazione in modo che abbia plausibile
// data civile di inizio e poi, di fine.
//
function gregorianoingg(aa,mm,g){
    var a,am,m,im=["Eccesso mensile",0,1,-1,0,0,1,1,2,3,3,4,4];
    a=Math.round(aa);
    m=Math.round(mm+119)%12+1;
    am=a*12+m+47999997;
    //
    // Il Giorno Giuliano del primo gennaio dell'anno zero
    // deve essere 1721060 per cui impongo la costante 751030.
    //
    return (751030+g+30*m+im[m]+365*a+
           (am-am%48)/48-(am-am%1200)/1200+(am-am%4800)/4800);
    }
//
// PER VERIFICHE :
// Il 31 gennaio  1585 a mezzogiorno e' stato il Giorno Giuliano 2300000
// ed era giovedi'.
// Il 16 novembre 1858 a mezzogiorno e' stato il Giorno Giuliano 2400000
// ed era martedi'.
// L' 1 gennaio 2001 a mezzogiorno, lunedi', e' stato il Giorno Giuliano 
// 2451911 e dividendo per 7 si ottiene il resto 0 corrisponde a lunedi' 
// e quindi il resto 6 corrisponde alla domenica ed io, nato il giorno 
// 24 maggio 1946 ossia 2431965, sono nato di venerdi'.
/*

AMEN LIBRERIA DORMAND PRINCE - 5 giugno 2014

*/ //