// polynomnullstellen_01.js

// polynomnullstellen()                  Bestimmt Polynomnullstellen
//   pol_koeff(t,k,k_,kk_,maxgrad);      Polynomkoeffizientenbestimmung und Polynomgrad (g)
//     klammertest(t);                   Überprüft die Klammerung
//     parsePolynom(t,"x",k)             Polynomparser
//     trans_poly(t);                    Übersetzt den Eingabestring in mathematischen Ausdruck
//       parsefind(t,i,-1)               Parser
//     clear(k);                         Initialisiert Array
//     calcKoeffs2(x1,y1,x2,y2,x3,y3,k); Numerik
//     Test(k,g,t,false);                Numerik
//     GLSL(m,k,g+1);                    Bildet Lösungsvektor
//   solvePolynom(g);                    Nullstellen bis Grad g=4
//     sgn(g);
//     Quad(a_,b_,c_);                   Löst quadratische Gleichung
//       GL("x",0,0,a,b,c);              Formatierungen
//       CheckDez(0,a,b,c,-p/2-Math.sqrt(r),1000000000);
//       Newton(x1r,x1i,0,0,a,b,c,nNw);
//         DNull(xr,xi,a,b,c,d,e);
//         Runden_(xr);
//           F(xr,xi,a,b,c,d,e);
//         L(nwr,nwi);                   Lösungsvektor
//       test(0,0,a_,b_,c_,2);
//       CheckKomplex(0,0,a,b,c,x1r,x1i,0.000001);
//     Kub(a_,b_,c_,d_);                 Löst Kubische Gleichungen
//     QQuad(a_,b_,c_,d_,e_);            Löst biquadratische Gleichungen
//       sqrk(-x1r,-x1i,W1r,W1i);
//   nst_approx(g,k,kk,k_,kk_);          bestimmt die Nullstellen durch Aproximation
//     Ableitung(k,kk,g);
//     HornerR(k,g,i);
//     polydivR(k,g,i);
//     NewtonR_(xr,k,kk,gg,200);
//     Newton_(xr,xi,k_,kk_,gg,100,Y);
//       HornerK(kk,g-1,xr,xi,Y);
//     polydivRK(k,g,y[0],y[1]);
//     DNull_(Y[0],Y[1],k_,gg);
//     sortiere(xxr,xxi,n);
//     runden(xxr[j]);

// ---------------------------------------------------------


function polynomnullstellen(t)
 {
  var i;
  var maxgrad=20;   // maximaler grad
  var T="",g;
  var k=new Array(maxgrad),kk=new Array(maxgrad);
  var k_=new Array(maxgrad),kk_=new Array(maxgrad);

  g=pol_koeff(t,k,k_,kk_,maxgrad);   //liefert die Koeffizienten des Polynoms und den Grad (g)
  if((g<3)&&(k[0]==0)&&(k[1]==0)&&(k[2]==0))
   {
    alert("Bitte eine sinnvolle Eingabe machen");
    document.f.inp.value="x^2-2x+1";
    return;
   }
  if(k[g]<0)
   for(i=0;i<=g;i++)
    k[i]=-k[i];

    Ableitung(k,kk,g);
    Ableitung(k_,kk_,g);

  //alert("g = "+g+"\nk = "+k+"\nkk = "+kk+"\nk_ = "+k_+"\nkk_ = "+kk_);

// ------------------------- nullstellen berechnen -------------------------------

  switch(g)                  // 2. 3. und 4. grades mit solvePolynom() lösen
      {
       case 2:
        k_o[2]=k[2];
        k_o[1]=k[1];
        k_o[0]=k[0];
        solvePolynom(2);
        break;
       case 3:
        k_o[3]=k[3];
        k_o[2]=k[2];
        k_o[1]=k[1];
        k_o[0]=k[0];
        solvePolynom(3);
        break;
       case 4:
        k_o[4]=k[4];
        k_o[3]=k[3];
        k_o[2]=k[2];
        k_o[1]=k[1];
        k_o[0]=k[0];
        solvePolynom(4);
        break;
       default:
      }

  nst_approx(g,k,kk,k_,kk_);  // bestimmt die Nullstellen durch Aproximation

 }

// ---------------------------------------------------------------------- //

  function pol_koeff(t,k,k_,kk_,maxgrad)
 {
  var i,j;
  var g=2,gg,versuch,klammer,temp;

  g=2;
  klammer=t.indexOf("(");

  if(klammer==-1)  // keine Klammer im Eingabestring
   {
    clear(k);               // initialisiert Array k mit 0
    parsePolynom(t,"x",k);  // liefert die koeffizienten des polynoms in k (array)
    g=k.length-1;
    gg=g;
   }

  t=trans_poly(t);  // übersetzt den Eingabestring in mathematischen Ausdruck

  if(klammer>-1)  // Eingabestring mit Klammer
   {
    var x1=-Math.random()*20,x2=Math.random()*10-5,x3=Math.random()*20;
    var y1=eval(t.replace(/X/g,"x1")+";");
    var y2=eval(t.replace(/X/g,"x2")+";");
    var y3=eval(t.replace(/X/g,"x3")+";");
    clear(k);
    //alert("x1 = "+x1+" x2 = "+x2+" x3 = "+x3+"\n"+"y1 = "+y1+" y2 = "+y2+" y3 = "+y3);
    // liefert drei verschiedene Funktionswerte vom mathem. Ausdruck t

    calcKoeffs2(x1,y1,x2,y2,x3,y3,k);  // berechnet damit irgend was (in k[0],k[1],k[2])

    gg=2;

    if(!Test(k,g,t,false))
     {
      versuch++;
      for(g=3;g<=maxgrad;g++)
       {
        var m=new Array((g+1)*(g+2));
        clear(m);
        for(i=0;i<m.length;i++)
         m[i]=0;
        x1=-g/2;
        for(i=0;i<g+1;i++)
         {
          x1+=Math.round(Math.random()*20)/10;
          m[(g+2)*i+g+1]=eval(t.replace(/X/g,"x1"));
          while(Math.abs(m[(g+2)*i+g+1])==(1/0))
           {
            x1+=Math.round(Math.random()*20)/10;
            m[(g+2)*i+g+1]=eval(t.replace(/X/g,"x1"));
           }
          m[(g+2)*i]=1;
          for(j=1;j<g+1;j++)
           m[(g+2)*i+j]=m[(g+2)*i+j-1]*x1;
         }
        clear(k);
        GLSL(m,k,g+1);
        gg=g;
        if(Test(k,g,t,true))
         break;
       }
      if(g>=maxgrad)
       {
        if(!Test(k,gg,t,true))
         {
          if(versuch<5)
          {
           meldetext=meldetext+"<br>versuch<5";
           solvePolynom();
          }
          else
           versuch=0;
          return;
         }
       }
     }
   }
   //alert("k = "+k+" g = "+g); k enthält die koeffizienten von hinten nach vorn

// ------------------ ende if((klammer==-1)&&(N=="")) ------------------

  g=gg;

  for(i=0;i<=g;i++)
   {
    if(Math.abs(k[i]-Math.round(k[i]))<1e-5)k[i]=Math.round(k[i]);
     k_[i]=k[i];
   }

  while((k[g]==0)&&(g>2))
   g--;
//-----------------------------------------
  grad=g;
  for(i=0;i<=g;i++)
   a[g-i]=k_[g-i];  // funktionskoeffizienten und grad sind bekannt
  //alert("a = "+a+" g = "+g);
//------------------------------------------

  return g;
 }

// --------------------------------------------------------------

function nst_approx(g,k,kk,k_,kk_)
 {
  //alert("g = "+g+"\nk = "+k+"\nkk = "+kk+"\nk_ = "+k_+"\nkk_ = "+kk_);
  var i,j;
  var gg=g;
  var dvk=0;
  var nvk=100;                    // suchzeit
  var n=0,nreell,xxr=new Array(g),xxi=new Array(g);
  var counter=0;

  while(k[0]==0)
   {
    xxr[n]=0;
    xxi[n]=0;
    for(j=0;j<g;j++)
     k[j]=k[j+1];
    k[g]=0;
    g--;
    n++;
    nanz=n;           // anzahl der Nullstellen (global)
    Ableitung(k,kk,g);
    if(g==0)
     break;
    if(g==1)
     {
      xxr[n]=-k[0]/k[1];
      xxi[n++]=0;
      g=0;
      break;
     }
   }  // ende while(k[0]==0)

  for(i=-50;(i<=50) && (n<gg);i+=0.25)
   {
    var y;
    while(Math.abs(y=HornerR(k,g,i))<1e-10)
     {
      xxr[n]=i;
      xxi[n]=0;
      polydivR(k,g,i);

      while((k[g]==0)&&(g>1))
       g--;
      n++;
      nanz=n;           // anzahl der Nullstellen (global)
      Ableitung(k,kk,g);
      if(g==0)
       break;
      if(g==1)
       {
        xxr[n]=-k[0]/k[1];
        xxi[n++]=0;
        g=0;
        break;
       }
     } // ende  while(Math.abs(y=HornerR(k,g,i))<1e-10)
   } // ende for(i=-50;(i<=50) && (n<gg);i+=0.25)





  counter=0;

//alert("1. g = "+g+" n = "+n+" gg = "+gg+" counter while((i<gg)&&(n<gg)) = "+counter);
  i=0;
  while((i<gg)&&(n<gg))
   {
    counter++;
    i++;
    var xr=(Math.random()*Math.random()*20.0-5)*i/5;
    xi=0;
    var y=0;
    //alert("k = "+k+"\nk_ = "+k_+"\nkk = "+kk+"\nkk_ = "+kk_+"\ngg = "+gg);
    if((y=NewtonR_(xr,k,kk,gg,200))!=false)
     {
      if(Math.abs(HornerR(k_,gg,y))>1e-10)
       continue;
      for(j=0;j<n;j++)
       if(runden(xxr[j])==runden(y))
        break;
      if(j<n)
       continue;
      xxr[n]=y;
      xxi[n]=0;
      polydivR(k,g,y);

      while((k[g]==0)&&(g>1))
       g--;
      n++;
      nanz=n;           // anzahl der Nullstellen
      //alert("n1 = "+n);
      Ableitung(k,kk,g);
      if(g==0)
       break;

      if(g==2)
       {
        k[0]/=k[2];
        k[1]/=k[2];
        k[2]=1;

        var D=k[1]*k[1]/4-k[0];
        var x1,x2,xi,xr,Y=new Array(0,0);

        if(D>=0)
         {
          x1=-k[1]/2-Math.sqrt(D);
          y=NewtonR_(x1,k_,kk_,gg,100);
          if(Math.abs(HornerR(k_,gg,y))<1e-8)
           {
            xxi[n]=0;
            xxr[n++]=y;
            nanz=n;           // anzahl der Nullstellen
            //alert("n2 = "+n);
            polydivR(k,g,y);
           }
          x2=-k[1]/2+Math.sqrt(D);
          y=NewtonR_(x2,k_,kk_,gg,100);
          if(Math.abs(HornerR(k_,gg,y))<1e-8)
           {
            xxi[n]=0;
            xxr[n++]=y;
            nanz=n;           // anzahl der Nullstellen
            //alert("n3 = "+n);
            polydivR(k,g,y);
           }
          Ableitung(k,kk,g);
         }
        else
         {
          xr=-k[1]/2;
          xi=-Math.sqrt(-D);
          var erg=Newton_(xr,xi,k_,kk_,gg,100,Y);

          if(true)
           {
            xxr[n]=Y[0];
            xxi[n++]=Y[1];
            nanz=n;           // anzahl der Nullstellen
            //alert("n4 = "+n);
            xxr[n]=Y[0];
            xxi[n++]=-Y[1];
            nanz=n;           // anzahl der Nullstellen
            //alert("n5 = "+n);
           }
         }  // ende if(D>=0)
       }  // ende if(g==2)

      if(g==1)
       {
        y=-k[0]/k[1];
        xxi[n]=0;
        g=0;
        y=NewtonR_(y,k_,kk_,gg,100);
        if(Math.abs(HornerR(k_,gg,y))<1e-8)
         {
          xxr[n++]=y;
          nanz=n;           // anzahl der Nullstellen
          break;
         }
       }
     }  //   ende  if((y=NewtonR_(xr,k,kk,gg,200))!=false)
   }  //     while((i<gg)&&(n<gg))

  //alert("2. g = "+g+" n = "+n+" gg = "+gg+" counter  while((i<nvk+gg)&&(n<gg)) = "+counter);


  var tryconj=(1==0),jetzt=new Date();
  nreell=n;
  var millis=jetzt.getTime(), dvkstop=millis+dvk*1000;
  var kr=new Array(g+1),ki=new Array(g+1);
  for(i=0;i<=g;i++)
   {
    kr[i]=k[i];
    ki[i]=0;
   }





  counter=0;
  i=0;
  while((i<nvk+gg)&&(n<gg))
   {
    counter++;
    i++;
    var proz=Math.floor(i*100/(nvk+g));
    if(nvk>10000)
    proz=Math.floor(100*(n-nreell)/(gg-nreell));
    if(dvk>0)
     {
      if((jetzt=new Date()).getTime()>dvkstop)
       break;
      proz=Math.floor(100*(1-(dvkstop-jetzt.getTime())/dvk/1000));
     }
    var xr,yr;
    if(!tryconj)
     {
      if(i<100)
       {
        xr=(Math.random()*20.0-10)*i/10;
        xi=(Math.random()*20.0-10)*i/10;
        if(Math.random()>.8)
         {
          xr*=100;
          xi*=100;
         }
       }
      else
       {
        xr=(Math.random()*Math.random()*Math.random()*Math.random()*1000.0);
        xi=(Math.random()*Math.random()*Math.random()*Math.random()*1000.0);
        if(Math.random()>.5)
         xr=-xr;
        if(Math.random()>.5)
         xi=-xi;
       }
     }
    else
     {
      xi=-xi;
      i--;
     }

    if(i<gg)
     {
      xr=-((gg%2)-.5)*2*Math.cos(i*2*Math.PI/gg)/k_[gg];
      xi=Math.sin(i*2*Math.PI/gg)/k_[gg];
     }

    var y=new Array(0,0),erg=false;

    if((Math.random()>.5)&&(i>gg))
     erg=Newton_(xr,xi,k,kk,g,100,y);
    else erg=Newton_(xr,xi,k_,kk_,gg,100,y);
     if(erg)
      {
       if(isNaN(y[0]))
        continue;
       if(DNull_(y[0],y[1],k_,gg)>1e-5)
        continue;
       for(j=0;j<n;j++)
        if((runden(xxr[j])==runden(y[0]))&&(runden(xxi[j])==runden(y[1])))
         break;
       if(j<n)
        continue;
       xxr[n]=y[0];
       xxi[n]=y[1];
       while((k[g]==0)&&(g>1))
        g--;
       n++;
       nanz=n;           // anzahl der Nullstellen
       for(j=0;j<n;j++)
        if((runden(xxr[j])==runden(y[0]))&&(-runden(xxi[j])==runden(y[1])))
         break;
       tryconj=(j==n);
       if(tryconj)
        {
         if(polydivRK(k,g,y[0],y[1]))
          {
           xxr[n]=y[0];
           xxi[n++]=-y[1];
           nanz=n;           // anzahl der Nullstellen
           Ableitung(k,kk,g);
          }
         tryconj=false;
        }
       while((k[g]==0)&&(g>1))
        g--;
      }     //   ende     if(erg)
   }         //   ende    while((i<nvk+gg)&&(n<gg))


// -----------------------------------------------------------------

  if(n>0)
   {
    var Y=new Array(0,0),x_=0;
    nanz=n;           // anzahl der Nullstellen
    for(i=0;i<n;i++)
     {
      if(xxi[i]!=0)
       if(Newton_(xxr[i],xxi[i],k_,kk_,gg,200,Y))
        {
         if(DNull_(Y[0],Y[1],k_,gg)<DNull_(xxr[i],xxi[i],k_,gg))
          {
           xxr[i]=Y[0];xxi[i]=Y[1];
          }
        }
       else
        {
         x_=NewtonR_(xxr[i],k_,kk_,gg,500);
          if( Math.abs(HornerR(k_,gg,x_)) < Math.abs(HornerR(k_,gg,xxr[i])) )
           xxr[i]=x_;
        }
     }
    sortiere(xxr,xxi,n);

    for(i=0;i<n-1;i++)
     {
      if((Math.abs(xxr[i]-xxr[i+1])<1e-12)&&(xxi[i]>xxi[i+1]))
       {
        var sw=xxr[i];
        xxr[i]=xxr[i+1];
        xxr[i+1]=sw;
        sw=xxi[i];
        xxi[i]=xxi[i+1];
        xxi[i+1]=sw;
       }
     }
    for(i=0;i<n;i++)
     {
//----------------------------------------------------------------------------
      if(Math.abs(xxi[i])<1e-5)nst5[i+1]=xxr[i];     // nullstellen für grad > 4
//----------------------------------------------------------------------------
     }
    var mz=(gg-n==1)?"":"n";

    for(i=0;i<n;i++)
     {
      HornerK(k_,gg,xxr[i],xxi[i],Y);
      var ny;
     }
//-------------------------------------------------------

    if(gg<20)
     {
      var NSr=new Array(),NSi=new Array();
      var ans=String(" ,,,;");
      var ns=ans.split(";");

      for(i=0;i<ns.length;i++)
       {
        var nss=ns[i].split(",");
        NSr[i]=Number(nss[0]);
        NSi[i]=Number(nss[1]);
       }
      sortiere(NSr,NSi,ns.length);
      for(i=0;i<ns.length;i++)
       {
        if((Math.abs(NSr[i]-NSr[i+1])<1e-12)&&(NSi[i]>NSi[i+1]))
         {
          var sw=NSr[i];
          NSr[i]=NSr[i+1];
          NSr[i+1]=sw;
          sw=NSi[i];
          NSi[i]=NSi[i+1];
          NSi[i+1]=sw;
         }
       }
     }  // ende if(gg<20)

// -----------------------------------------------------------

   }  // ende  if(n>0)
  else
   {
    meldetext=meldetext+"<br>n!=>0 n = "+n;
   }
 }

// ---------------------------------------------------------------------- //

function calcKoeffs2(x1,y1,x2,y2,x3,y3,k)
{
k[2]=(x3*(y2-y1)+x2*(y1-y3)+x1*(y3-y2))/((x1-x2)*(x3-x1)*(x3-x2));
k[1]=(x3*x3*(y2-y1)+x2*x2*(y1-y3)+x1*x1*(y3-y2))/((x2-x1)*(x3-x1)*(x3-x2));
k[0]=(x3*x3*(x2*y1-x1*y2)+x3*(x1*x1*y2-x2*x2*y1)+x1*x2*y3*(x2-x1))/((x2-x1)*(x3-x1)*(x3-x2));
}

//--------------------------------------------------------------

// k:Koeffizienten, g: Grad, t:Term
function Test(k,g,t,a)
{
 var i;
        for(i=0;i<20;i++)
        {
                var x=(Math.random()*40-20)/g;
                var y1=HornerR(k,g,x),y2=eval(t.replace(/X/g,"x"));
                var A=a?y1:1;

                if(Math.abs((y1-y2)/A)>0.0000001)
                {
                        return false;
                }
        }
        return true;
}

//-------------------------------------------------------------

function HornerR(k,g,x)
{
 var i;
        var y=k[g];
        for(i=g-1;i>=0;i--)y=y*x+k[i];
        return y;
}

function HornerK(k,g,xr,xi,Y)
{
 var i;
        var yr=k[g],yi=0;
        for(i=g-1;i>=0;i--)
        {
                //xr·yr - yi·xi + kr + î·(yi·xr + xi·yr + ki)
                var yrr=yr*xr-yi*xi+k[i];
                yi=yi*xr+xi*yr;
                yr=yrr;
        }
        Y[0]=yr;Y[1]=yi;
}

// ----------------------------------------------------------

function runden(x)
{
        return Math.round(x*10000000)/10000000;
}

// --------------------------------------------------

function Newton_(xr,xi,k,kk,g,n,Y)
{
        var i;
        Y[0]=xr;Y[1]=xi;
        var d0=DNull_(xr,xi,k,g),d1,xrt=xr,xit=xi,yr,yi;
        var nwr=xr,nwi=xi;
        if(d0<1e-20)return true;
        for(i=0;i<n;i++)
        {
                HornerK(kk,g-1,xr,xi,Y);yyr=Y[0];yyi=Y[1];
                HornerK(k,g,xr,xi,Y);yr=Y[0];yi=Y[1];
                var N=(yyr*yyr+yyi*yyi);//if(N==0){break;}
                xrt-=(yr*yyr+yi*yyi)/N;
                xit+=(yr*yyi-yi*yyr)/N;
                if(Math.abs(xit)<1e-16)xit=0;
                Y[0]=xrt;Y[1]=xit;
                d1=DNull_(xrt,xit,k,g);
                if(d1>=d0){if(d0<1e-8)break;  return false;}
                d0=d1;
                xr=xrt;xi=xit;
                if(d0<1e-15)break;
        }
        nwr=xr;nwi=xi;
        Y[0]=nwr;Y[1]=nwi;
        return true;
}

// --------------------------------------------

function NewtonR_(x,k,kk,g,n)
{
        var i;
        var d0=Math.abs(HornerR(k,g,x)),d1,xt=x;
        var nw=x,y,yy,yyy;
        if(d0<1e-20)return x;
        for(i=0;i<n;i++)
        {
                y=HornerR(k,g,x);
                yy=HornerR(kk,g-1,x);
                if(yy==0){return false;}
                xt-=y/yy;
                yyy=HornerR(k,g,xt);
                if(y==yyy)break;
                d1=Math.abs(yyy);
                if((d1>d0)){if(d0<1e-12)break; return false;}
                d0=d1;
                x=xt;
                if(d0<1e-16){return x;}
        }
        return false;
}

// -----------------------------------------------

function DNull_(xr,xi,k,g)
{
        var y=new Array(0,0);//alert(g+"\n"+k+"\n"+L(xr,xi));
        HornerK(k,g,xr,xi,y);//alert(y);
        return Math.sqrt(y[0]*y[0]+y[1]*y[1]);
}

// -------------------------------------------------------

function Ableitung(k,kk,g)
{
 var i;
        for(i=0;i<g;i++)
        {
         kk[i]=k[i+1]*(i+1);
        }
}

// ---------------------------------------------------


function sortiere(x,y,xl)
{
    var L_=new Array(32),R=new Array(32);
    var s, i, j, LL, rr, v, w, ii;
    s=0; L_[0]=0; R[0]=xl-1;
    do
    {
        LL = L_[s]; rr = R[s];
        s--;
        do
        {
            i = LL; j = rr;
            v = x[Math.floor((LL + rr) / 2)];
            do
                {
                while(x[i]<v) i++;
                while(x[j]>v) j--;
                if (i <= j)
                {
                    w = x[i]; x[i] = x[j]; x[j] = w;
                    w = y[i]; y[i] = y[j]; y[j] = w;
                    i++; j--;
                }
            } while (i <= j);
            if (j - LL >= rr - 1)
            {
                if (LL < j)
                {
                    s++;
                    L_[s] = LL; R[s] = j;
                }
                LL = i;
            }
            else
            {
                if (i < rr)
                {
                    s++;
                    L_[s] = i; R[s] = rr;
                }
                rr = j;
            }
        } while (LL < rr);
    } while (s >= 0);
        return x;
}

// --------------------------------------------------------

function parsePolynom(p,v,K)
 {
  var PPP=p;
  p=p.replace(/—/g,"-").replace(/–/g,"-");
  p=(" "+p+" ").replace(/\+/g," +").replace(/-/g," -").replace(/x\^0 /g," ");
  p=" "+p.replace(/ /g,"").replace(/,/g,".").replace(/²/g,"2").replace(/³/g,"3").replace(/\^/g,"");
  p=p.replace(/·/g,"*").replace(/\*/g,"*").replace(/•/g,"*").replace(/,/g,".");
  p=p.replace(/\*x/g,v);
  p=p.replace(/xxxxxxxxxx/g,"x10").replace(/xxxxxxxxx/g,"x9");
  p=p.replace(/xxxxxxxx/g,"x8").replace(/xxxxxxx/g,"x7");
  p=p.replace(/xxxxxx/g,"x6").replace(/xxxxx/g,"x5");
  p=p.replace(/xxxx/g,"x4").replace(/xxx/g,"x3").replace(/xx/g,"x2");
  //p=p.replace(/x0/g,"*1");
  var pp=p.replace(/\d/g,"¶").replace(/,/g,"¶").replace(/\./g,"¶").replace(/p/g,"¶").replace(/_/g,"¶");
  var ppp=pp.replace(/\//g,"¶").replace(/\*/g,"¶");

  var i,je,jk,k,e,jj;
  var b=0;
  for(i=0;i<K.length;i++)
   K[i]=0;

  for(i=0;i<p.length;i++)
   {
    if(pp.charAt(i)!=v)
     continue;
    for(jk=i-1;jk>=0;jk--)
     {
      if(ppp.charAt(jk)!="¶")
       break;
     }
    k=Number(p.substring(jk,i));
    if(jk==i-1)
     k=(p.charAt(jk)=="-")?-1:1;
    for(je=i+1;je<pp.length;je++)
     {
      if(pp.charAt(je)!="¶")
       break;
     }
    e=Number(p.substring(i+1,je));
    for(jj=je;jj<pp.length;jj++)
     {
      if(jj==ppp.length-1)
       jj++;
      if((ppp.charAt(jj)=="+")||(ppp.charAt(jj)=="-")||(jj==ppp.length))
       {
        if(jj>je)
         {
          pp=pp.substr(0,i)+pp.substring(je,jj)+pp.substring(i,je)+pp.substring(jj,pp.length);
          ppp=ppp.substr(0,i)+ppp.substring(je,jj)+ppp.substring(i,je)+ppp.substring(jj,pp.length);
          p=p.substr(0,i)+p.substring(je,jj)+p.substring(i,je)+p.substring(jj,p.length);
          i+=(jj-je);
          je=jj;
         }
        break;
       }
     }
    if((je==i+1))
     e=1;
    if(p.charAt(jk)=="/")
     {
      for(jk=jk-1;jk>=0;jk--)
       {
        if(pp.charAt(jk)!="¶")
         break;
       }
      b=eval(p.substring(jk,i));
     }
    else if((k!=Math.floor(k))||(p.substring(jk,i).indexOf("p")>-1))
     {
      var b=eval(p.substring(jk,i));
     }
    else
     {
      b=k;
     }
    if(e>K.length-1)
     for(var ii=K.length;ii<=e;ii++)
      K[ii]=0;
     K[e]+=b;
//   alert("parse: "+PPP+"\n"+K[e].str()+"·"+v+"^"+e);
     for(i=jk;i<je;i++)
      p=p.substr(0,i)+" "+p.substring(i+1,p.length);
   }

  pp=p.replace(/ /g,"");
  if(pp.charAt(0)=="+")
   pp=pp.substr(1,pp.length);
  while((pp.length>0)&&(pp.substr(pp.length-1,1).match(/\d/)==null))
   pp=pp.substr(0,pp.length-1);
  b=eval(pp);

  if(!isNaN(b))K[0]+=b;
}

// ---------------------------------------------------------

function polydivR(k,g,x0)
{
        q=new Array(g);
        kk=new Array(g+1);
        var i,gg=g;
        for(i=0;i<kk.length;i++)kk[i]=k[i];
        for(i=0;i<kk.length-1;i++)q[i]=0;
        while(g>0)
        {
                kk[g-1]+=kk[g]*x0;
                q[g-1]=kk[g];
                kk[g]=0;
                while((kk[g]==0)&&(g>0))g--;
        }
        if((Math.abs(kk[g])>1e-8)||(g>0)){return false;}
        k[gg]=0;
        for(i=0;i<q.length;i++)k[i]=q[i];
        return true;
}

// -----------------------------------------------------------

function polydivRK(k,g,xr,xi)
{
        q=new Array(g);
        kk=new Array(g+1);
        var i,gg=g,a=-2*xr,b=xr*xr+xi*xi;
        for(i=0;i<kk.length;i++)kk[i]=k[i];
        for(i=0;i<kk.length-1;i++)q[i]=0;
        while(g>0)
        {
                if(g>1)q[g-2]=kk[g];
                kk[g-1]-=kk[g]*a;
                if(g>1)kk[g-2]-=kk[g]*b;
                kk[g]=0;
                while((kk[g]==0)&&(g>0))g--;
        }
        k[gg]=0;
        for(i=0;i<q.length;i++)k[i]=q[i];
        return true;
}

// ----------------------------------------------------------

function clear(k)  // initialisiert array
 {
  var i;
        for(i=0;i<k.length;i++)
        k[i]=0;
 }

// -------------------------------------------------------------

function solvePolynom(g)
{
        Erl=(g<0);g=g*sgn(g);
        var a_,b_,c_,d_,e_;

        if (g==2)
        {
                a_=k_o[2];
                b_=k_o[1];
                c_=k_o[0];

                if (a_==0)
                 {
                  Quad(a_,b_,c_);
                  Newton(x1r,x1i,0,0,a_,b_,c_,nNw);
                  if(Math.abs(x1i)<1e-5)nst[1]=x1r;
                  test(0,0,a_,b_,c_,2);
                  return;
                 }

                Quad(a_,b_,c_);
                Newton(x1r,x1i,0,0,a_,b_,c_,nNw);
                if(Math.abs(x1i)<1e-5)nst[1]=x1r;
                if((x1r!=x2r)||(x1i!=x2i))
                Newton(x2r,x2i,0,0,a_,b_,c_,nNw);
                if(Math.abs(x2i)<1e-5)nst[2]=x2r;
                test(0,0,a_,b_,c_,2);
        }

        if (g==3)
        {
                a_=k_o[3];
                b_=k_o[2];
                c_=k_o[1];
                d_=k_o[0];

                if (a_==0)
                {
                        Quad(b_,c_,d_);
                        Newton(x1r,x1i,0,0,b_,c_,d_,nNw);
                        if(Math.abs(x1i)<1e-5)nst[1]=x1r;
                        Newton(x2r,x2i,0,0,b_,c_,d_,nNw);
                        if(Math.abs(x2i)<1e-5)nst[2]=x2r;
                        test(0,0,b_,c_,d_,2);
                        return;
                }

                Kub(a_,b_,c_,d_);
                Newton(x1r,x1i,0,a_,b_,c_,d_,nNw);
                if(Math.abs(x1i)<1e-5)nst[1]=x1r;
                Newton(x2r,x2i,0,a_,b_,c_,d_,nNw);
                if(Math.abs(x2i)<1e-5)nst[2]=x2r;
                Newton(x3r,x3i,0,a_,b_,c_,d_,nNw);
                if(Math.abs(x3i)<1e-5)nst[3]=x3r;
                test(0,a_,b_,c_,d_,3);
        }

        if (g==4)
        {
                a_=k_o[4];
                b_=k_o[3];
                c_=k_o[2];
                d_=k_o[1];
                e_=k_o[0];

                if ((a_==0)&&(b_==0))
                {
                        Quad(c_,d_,e_);
                        Newton(x1r,x1i,0,0,c_,d_,e_,10);
                        if(Math.abs(x1i)<1e-5)nst[1]=x1r;
                        Newton(x2r,x2i,0,0,c_,d_,e_,10);
                        if(Math.abs(x2i)<1e-5)nst[2]=x2r;
                        test(0,0,c_,d_,e_,2);
                        return;
                }

                if (a_==0)
                {
                        Kub(b_,c_,d_,e_);
                        Newton(x1r,x1i,0,b_,c_,d_,e_,nNw);
                        if(Math.abs(x1i)<1e-5)nst[1]=x1r;
                        Newton(x2r,x2i,0,b_,c_,d_,e_,nNw);
                        if(Math.abs(x2i)<1e-5)nst[2]=x2r;
                        Newton(x3r,x3i,0,b_,c_,d_,e_,nNw);
                        if(Math.abs(x3i)<1e-5)nst[3]=x3r;
                        test(0,b_,c_,d_,e_,3);
                        return;
                }

                QQuad(a_,b_,c_,d_,e_);
                Newton(x1r,x1i,a_,b_,c_,d_,e_,nNw);x1r=nwr;x1i=nwi;
                if(Math.abs(x1i)<1e-5)nst[1]=x1r;
                Newton(x2r,x2i,a_,b_,c_,d_,e_,nNw);x2r=nwr;x2i=nwi;
                if(Math.abs(x2i)<1e-5)nst[2]=x2r;
                Newton(x3r,x3i,a_,b_,c_,d_,e_,nNw);x3r=nwr;x3i=nwi;
                if(Math.abs(x3i)<1e-5)nst[3]=x3r;
                Newton(x4r,x4i,a_,b_,c_,d_,e_,nNw);x4r=nwr;x4i=nwi;
                if(Math.abs(x4i)<1e-5)nst[4]=x4r;
                 test(a_,b_,c_,d_,e_,4);
        }
}

// -----------------------------------------------------------

function test(a,b,c,d,e,g)
{
        var xr=x1r,xi=x1i,xr2=x1r*x1r,xr3=xr2*x1r,xr4=xr2*xr2,xi2=x1i*x1i,xi3=xi2*x1i,xi4=xi2*xi2;
        var ch_re=a*(xi4 - 6.0*xi2*xr2+xr4)+b*xr*(xr2-3.0*xi2)+c*(xr2-xi2)+d*xr+e;
        var ch_im=-xi*(4.0*a*xr*(xi2-xr2)+b*(xi2-3.0*xr2)-2.0*c*xr-d);
        if(xr2="")return;

        xr=x2r,xi=x2i,xr2=x2r*x2r,xr3=xr2*x2r,xr4=xr2*xr2,xi2=x2i*x2i,xi3=xi2*x2i,xi4=xi2*xi2;
        ch_re=a*(xi4 - 6.0*xi2*xr2+xr4)+b*xr*(xr2-3.0*xi2)+c*(xr2-xi2)+d*xr+e;
        ch_im=-xi*(4.0*a*xr*(xi2-xr2)+b*(xi2-3.0*xr2)-2.0*c*xr-d);
        if(g==2)return;

        var xr=x3r,xi=x3i,xr2=x3r*x3r,xr3=xr2*x3r,xr4=xr2*xr2,xi2=x3i*x3i,xi3=xi2*x3i,xi4=xi2*xi2;
        ch_re=a*(xi4 - 6.0*xi2*xr2+xr4)+b*xr*(xr2-3.0*xi2)+c*(xr2-xi2)+d*xr+e;
        ch_im=-xi*(4.0*a*xr*(xi2-xr2)+b*(xi2-3.0*xr2)-2.0*c*xr-d);
        if(g==3)return;

        var xr=x4r,xi=x4i,xr2=x4r*x4r,xr3=xr2*x4r,xr4=xr2*xr2,xi2=x4i*x4i,xi3=xi2*x4i,xi4=xi2*xi2;
        ch_re=a*(xi4 - 6.0*xi2*xr2+xr4)+b*xr*(xr2-3.0*xi2)+c*(xr2-xi2)+d*xr+e;
        ch_im=-xi*(4.0*a*xr*(xi2-xr2)+b*(xi2-3.0*xr2)-2.0*c*xr-d);

}

// -------------------------------------------------------------

function Newton(xr,xi,a,b,c,d,e,n)
{
        var i;
        var bb=a*4,cc=b*3,dd=c*2,ee=d,d0=DNull(xr,xi,a,b,c,d,e),d1,xrt=xr,xit=xi;
        nwr=xr;nwi=xi;
        if(d0==0)return L(xr,xi);
        for(i=0;i<n;i++)
        {
                F(xr,xi,a,b,c,d,e);yr=fxr;yi=fxi;
                F(xr,xi,0,bb,cc,dd,ee);yyr=fxr;yyi=fxi;
                var N=(yyr*yyr+yyi*yyi);if(N==0){break;}
                xrt-=(yr*yyr+yi*yyi)/N;
                xit+=(yr*yyi-yi*yyr)/N;
                if(Math.abs((yr*yyr-yi*yyi)/N)>0.5)break;
                d1=DNull(xr,xi,a,b,c,d,e);
                if(d1>d0)break;
                d0=d1;
                xr=xrt;xi=xit;
        }
        nwr=Runden_(xr);nwi=Runden_(xi);
        return(L(nwr,nwi));
}

// -----------------------------------------------------

function F(xr,xi,a,b,c,d,e)
{
        var xr2=xr*xr,xr3=xr2*xr,xr4=xr2*xr2,xi2=xi*xi,xi3=xi2*xi,xi4=xi2*xi2;
        fxr=a*(xi4 - 6.0*xi2*xr2+xr4)+b*xr*(xr2-3.0*xi2)+c*(xr2-xi2)+d*xr+e;
        fxi=-xi*(4.0*a*xr*(xi2-xr2)+b*(xi2-3.0*xr2)-2.0*c*xr-d);
}

// -------------------------------------------------------------

function DNull(xr,xi,a,b,c,d,e)
{
        F(xr,xi,a,b,c,d,e)
        return Math.sqrt(fxr*fxr+fxi*fxi);
}

// --------------------------------------------------------------

function L(r,it)
{
        var t=new String(r);
        if (it>0)
                t+=" + "+it+"·î";
        else if (it<0)
                t+=" - "+Math.abs(it)+"·î"
        if(t.charAt(0)==".")t=0+t;
        return t.replace(/\./g,",").replace(/-,/g,"-0,").replace(/ ,/g," 0,").replace(/ 1·î/," î").replace(/0 \+ /,"").replace(/0 - /,"-");
}

// --------------------------------------------------------------

function Quad(a,b,c)
{
 var dummy="";
        GLL=GL("x",0,0,a,b,c)+"= 0 ";
        if(a==0)
        {
                if(b==0)
                {
                 x1r="";x2r="";x1i=0;x2i=0;return;
                }
                x1r=-c/b;x1i=0;
                x2r=x1r;x2i=0;
                if(Erl)
                {
                 dummy="1";
                }
                return 1;
        }
        var p=b/a,q=c/a;
        var r=p*p/4-q;
        if (r>0)
        {
                x1r=CheckDez(0,a,b,c,-p/2-Math.sqrt(r),1000000000);x1i=0;
                x2r=CheckDez(0,a,b,c,-p/2+Math.sqrt(r),1000000000);x2i=0;
        }
        else if(r==0)
        {
                x1r=-p/2;x1i=0;
                x2r=x1r;x2i=x1i;
        }
        else
        {
                x1r=-p/2;x1i=-Math.sqrt(-r);
                x2r=-p/2;x2i=Math.sqrt(-r);
        }

        Newton(x1r,x1i,0,0,a,b,c,nNw);x1r=nwr;x1i=nwi;
        Newton(x2r,x2i,0,0,a,b,c,nNw);x2r=nwr;x2i=nwi;

    x1r=Runden_(x1r);
    x1i=Runden_(x1i);
    x2r=Runden_(x2r);
    x2i=Runden_(x2i);

    CheckKomplex(0,0,a,b,c,x1r,x1i,0.000001);
    CheckKomplex(0,0,a,b,c,x2r,x2i,0.000001);

        if((Erl)&&(b!=0))
        {
                pp=(p<0)?"("+p+")":String(p);
        }
        if((Erl)&&(b==0))
        {
          dummy = "1";
        }

        return 2;
}


// -----------------------------------------------------------

function QQuad(A,B,C,D,E)
{
        var iz,jz;
        if(A==0)
        return Kub(B,C,D,E);
        var a=B/A, b=C/A, c=D/A, d=E/A, a4=a/4, ERL=false;
        var p=b-3*a*a/8, q=a*(a*a/8-b/2)+c,r=-(3*a*a*a*a-16*a*a*b+64*a*c-256*d)/256;
        var xq1r,xq1i,xq2r,xq2i;

        if((Erl)&&((B!=0)||(D!=0)))
        {
                GLL=GL("x",A,B,C,D,E)+"= 0 ";
                if(B!=0)
                {
                 dummy="1";
                }
                else
                ERL=true;//Erl=false;
        }
        if((Erl)&&(B==0)&&(D==0))
        {
                GLL=GL("x",A,0,C,0,E)+"= 0 ";
                Quad(A,C,E);
                xq1r=x1r;xq1i=x1i;xq2r=x2r;xq2i=x2i;
                Erl=false;ERL=true;
        }

        var n=Kub(1,-2*p,p*p-4*r,q*q);
        if((Erl)&&((B!=0)||(D!=0)))
        {
                Erl=true;
        }
        W1r=new Array(0.0,0.0);
        W2r=new Array(0.0,0.0);
        W3r=new Array(0.0,0.0);
        W1i=new Array(0.0,0.0);
        W2i=new Array(0.0,0.0);
        W3i=new Array(0.0,0.0);
        sqrk(-x1r,-x1i,W1r,W1i);
        sqrk(-x2r,-x2i,W2r,W2i);
        sqrk(-x3r,-x3i,W3r,W3i);
        d0=Math.abs(W1r[0]*(W2r[0]*W3r[0]-W2i[0]*W3i[0])-W1i[0]*(W2r[0]*W3i[0]+W2i[0]*W3r[0])+q);
        d1= Math.abs(W1r[0]*(W2r[0]*W3r[0]-W2i[0]*W3i[1])-W1i[0]*(W2r[0]*W3i[1]+W2i[0]*W3r[1])+q);
        d2= Math.abs(W1r[0]*(W2r[1]*W3r[0]-W2i[1]*W3i[0])-W1i[0]*(W2r[1]*W3i[0]+W2i[1]*W3r[0])+q);

        iz=((d0<=d1)&&(d0<=d2))? 0:((d1<d2)?1:2);
        jz=0;
        if(iz==2)
         {
          iz=0;
          jz=1;
         }
        if((Erl)&&((B!=0)||(D!=0)))
        {
         meldetext=meldetext+"<br>if((Erl)&&((B!=0)||(D!=0)))";
        }
        x1r = (W1r[0]+W2r[jz]+W3r[iz])/2-a4;
        x1i = (W1i[0]+W2i[jz]+W3i[iz])/2;
        x2r = (W1r[0]-W2r[jz]-W3r[iz])/2-a4;
        x2i = (W1i[0]-W2i[jz]-W3i[iz])/2;
        x3r = (-W1r[0]+W2r[jz]-W3r[iz])/2-a4;
        x3i = (-W1i[0]+W2i[jz]-W3i[iz])/2;
        x4r = (-W1r[0]-W2r[jz]+W3r[iz])/2-a4;
        x4i = (-W1i[0]-W2i[jz]+W3i[iz])/2;
        Newton(x1r,x1i,A,B,C,D,E,nNw);
        x1r=nwr;
        x1i=nwi;
        Newton(x2r,x2i,A,B,C,D,E,nNw);
        x2r=nwr;
        x2i=nwi;
        Newton(x3r,x3i,A,B,C,D,E,nNw);
        x3r=nwr;
        x3i=nwi;
        Newton(x4r,x4i,A,B,C,D,E,nNw);
        x4r=nwr;x4i=nwi;
        if((Erl)&&((B!=0)||(D!=0)))
        {
         meldetext=meldetext+"<br>if((Erl)&&((B!=0)||(D!=0)))";
        }
        if((ERL)&&(B==0)&&(D==0))
        {
         meldetext=meldetext+"<br>if((ERL)&&(B==0)&&(D==0))";
        }
        return 4;
}

// ----------------------------------------------------------------------


function CheckDez(a,b,c,d,xr,dez)
{
        var X=Math.floor(xr*dez +.5)/dez;
        if (Math.abs(X*(X*(a*X+b)+c)+d)<1/dez) return X; else return xr;
}

// ---------------------------------------------------------------------


function CheckKomplex(a,b,c,d,e,xr,xi)
{
        var xr2=xr*xr,xr3=xr2*xr,xr4=xr2*xr2,xi2=xi*xi,xi3=xi2*xi,xi4=xi2*xi2;
        var ch_re=a*(xi4 - 6.0*xi2*xr2+xr4)+b*xr*(xr2-3.0*xi2)+c*(xr2-xi2)+d*xr+e;
        var ch_im=-xi*(4.0*a*xr*(xi2-xr2)+b*(xi2-3.0*xr2)-2.0*c*xr-d);
        return( ch_re*ch_re+ch_im*ch_im);
}

// ---------------------------------------------------------------------


function Runden_(x)
{
        var xx=String(x);
        if ((xx.indexOf("000000000")>=0)||(xx.indexOf("999999999")>=0)) x=Math.round(x*100000000)/100000000;
        if(Math.abs(x)<1.0e-20)x=0;
        return x;
}

// -----------------------------------------------------------

function sgn(x){if(x>0)return 1; else if(x<0)return -1; else return 0;}

// -------------------------------------------------------

function sqrk(a,b,wr,wi)
{
        var w=Math.sqrt(a*a+b*b),c=Math.sqrt((w+a)/2),d=Math.sqrt((w-a)/2);
        if(b<0)d=-d;
        wr[0]=-c;wi[0]=-d;
        wr[1]=c;wi[1]=d;
}

// ----------------------------------------------------------------

//Findet die Lösungen von Polynomen 3. Grades
function Kub(a,b,c,d)
 {
    if(a==0)return Quad(b,c,d);
    GLL=GL("x",0,a,b,c,d)+"= 0 ";

    pi = Math.PI;
    var n=-1;
    var r = b/a;
    var s = c / a;
    var t = d / a;
    var p = s - r * r / 3.0;
    var q = 2*r*r*r/27.0 - r*s/3.0 + t;
    var radikand = q * q / 4.0 + p * p * p / 27.0;
        if(Erl)
         {
          meldetext=meldetext+"<br>if(Erl) in Kub(a,b,c,d)";
         }
        if (radikand >=0)
         {
            var wurz = Math.sqrt(radikand);
            var u = Math.pow( Math.abs( -q / 2 + wurz), 1/3)*sgn(-q/2+wurz);
            var v = Math.pow(Math.abs(-q / 2 - wurz) , 1/3)*sgn(-q/2-wurz);
            x1r= u + v; x1i= 0;
            var im = (u - v) / 2 * Math.sqrt(3.0);
            x2r=-(u + v) / 2 ; x2i=-im;
            x3r= -(u + v) / 2 ; x3i= im;
                if (im !=0) n=1; else n=3;

                if(Erl)
                {
                  meldetext=meldetext+"<br>if(Erl) in Kub(a,b,c,d)";
                }
         }
        else
         {
          var rr = Math.sqrt(-p * p * p / 27.0);
          var cosphi = (-q / 2.0) / rr;
          var phi=Math.acos(cosphi);
          var dingens = 2.0 * Math.pow(rr , 1.0/3.0);
          x1r=dingens * Math.cos(phi/3.0); x1i= 0;
          x2r=dingens * Math.cos(phi/3.0 + 2.0 * pi / 3.0); x2i= 0;
          x3r=dingens * Math.cos(phi/3.0 + pi * 4.0 / 3.0); x3i= 0;
          n=3;
          if(Erl)
           {
            meldetext=meldetext+"<br>if(Erl) in Kub(a,b,c,d)";
           }
         }
    x1r -= r / 3.0;
    x2r -= r / 3.0;
    x3r -= r / 3.0;

    var xx;

    if(x1i==0)x1r=CheckDez(a,b,c,d,x1r,10000000000);
    if(x2i==0)x2r=CheckDez(a,b,c,d,x2r,10000000000);
    if(x3i==0)x3r=CheckDez(a,b,c,d,x3r,10000000000);
    if(n==3)
     {
        while((x1r>x2r)||(x2r>x3r))
         {
                if(x2r<x1r){ xx=x1r;x1r=x2r;x2r=xx;}
                if(x3r<x2r){ xx=x2r;x2r=x3r;x3r=xx;}
         }
     }
        Newton(x1r,x1i,0,1,r,s,t,nNw);x1r=nwr;x1i=nwi;
        Newton(x2r,x2i,0,1,r,s,t,nNw);x2r=nwr;x2i=nwi;
        Newton(x3r,x3i,0,1,r,s,t,nNw);x3r=nwr;x3i=nwi;

    x1r=Runden_(x1r);
    x1i=Runden_(x1i);
    x2r=Runden_(x2r);
    x2i=Runden_(x2i);
    x3r=Runden_(x3r);
    x3i=Runden_(x3i);
        if(Erl)
        {
                if(r!=0)
                {
                  meldetext=meldetext+"<br>if(r!=0) in Kub(a,b,c,d)";
                }
                else
                {
                  meldetext=meldetext+"<br>if(r==0) in Kub(a,b,c,d)";
                }
        }

        err=0;
    if((err=CheckKomplex(0.0,a,b,c,d,x1r,x1i,0.001))>0.1)
     meldetext=meldetext+"<br>Lösung 1 falsch: "+err;

    if((err=CheckKomplex(0.0,a,b,c,d,x2r,x2i,0.001))>0.1)
     meldetext=meldetext+"<br>Lösung 2 falsch: "+err;

    if((err=CheckKomplex(0.0,a,b,c,d,x3r,x3i,0.001))>0.1)
     meldetext=meldetext+"<br>Lösung 3 falsch: "+err;

    return n ;
 }

// -------------------------------------------------------------

function GL(v,a,b,c,d,e)
{
        var t="",aa=((a==1)||(a==-1))?((a==1)?"":"-"):String(a),
        bb=((b==1)||(b==-1))?((b==1)?"":"-"):String(b),
        cc=((c==1)||(c==-1))?((c==1)?"":"-"):String(c),
        dd=((d==1)||(d==-1))?((d==1)?"":"-"):String(d),
        ee=String(e);
        //alert(v+" "+a+" "+b+" "+c+" "+d+" "+e);
        if(a!=0)t=aa+v+"^4"; if(b!=0)t+="+"+bb+v+"³";
        if(c!=0)t+="+"+cc+v+"²"; if(d!=0)t+="+"+dd+v; if(e!=0)t+="+"+ee;
        t=" "+t.replace(/\+\-/g,"-").replace(/\+/g," + ").replace(/\./g,",").replace(/\-/g," - ").replace(/ ,/g," 0,").replace(/\+/g," + ").replace(/\s\s/g," ");
        //alert("|"+t+"  "+t.indexOf("+"));
        if(t.substr(0,4)=="  - ")t=" -"+t.substring(4,t.length);
        if(t.substr(0,3)=="  +")t=" "+t.substring(3,t.length);
        if(t==" ")t=" 0";
        return " "+t+" ";
}

// ---------------------------------------------------------

// m: Koeffizientenmatrix, v: Lösungsvektor, nz: Anzahl der Zeilen
function GLSL(m, v, nz)
{
        var i, j, k, ns=nz+1;
        var q;
        for (j = 0;j<ns-1;j++)
        {
                // Diagonalenfeld normalisieren
                q = m[j * ns + j];
                if (q == 0)
                {
                        //Gewährleisten, daß keine 0 in der Diagonale steht
                        for (i = j+1 ;i< nz;i++)
                        {
                                // Suche Reihe mit Feld <> 0 und addiere dazu
                                if (m[i * ns + j] != 0)
                                {
                                        for(k=0;k<ns;k++)m[j*ns+k]+=m[i*ns+k];
                                        q = m[j * ns + j];
                                    break;
                                }
                    }
                }
                if (q != 0)
                {
                    // Diagonalen auf 1 bringen
                        for(k=0;k<ns;k++)        m[j*ns+k]=m[j*ns+k]/q;
                }
                // Spalten außerhalb der Diagonalen auf 0 bringen
                for (i = 0 ; i< nz ; i++)
                {
                        if (i != j )
                        {
                                q = m[i * ns + j];
                                for(k=0;k<ns;k++)m[i*ns+k]-=q*m[j*ns+k];
                        }
                }
        }
        // Lösungsvektor füllen
        for(i=0;i<nz;i++) v[i]=m[(i+1)*ns-1];
}

// -------------------------------------------------------

function trans_poly(t)
 {
  var MultErg=new Array(/\dx/,/\d\(/,/\)\(/,/x\(/,/\)x/);
  var iz,jz,j;

  t=t.replace(/,/g,".").replace(/²/g,"^2").replace(/³/g,"^3");
  t=t.replace(/·/g,"*").replace(/ +/g,"");

  while(t.indexOf("xx")>-1)      // ersetzt xx durch x*x
   t=t.replace(/xx/,"x*x");

  for(j=0;j<MultErg.length;j++)   // fügt das * Zeichen ein
   do
    {
     iz=t.search(MultErg[j]);
     if(iz==-1)
      break;
      t=t.substr(0,iz+1)+"*"+t.substring(iz+1,t.length);
    }
   while(true);

   t="("+t+")";     // setzt den Ausdruck in klammern

   var n=0,d;
   var k=0,i=0;
   t=t.replace(/'/g,"^");

   if(t.indexOf("^")>-1)        // ersetzt z.B. x^2 durch Math.pow(x,2)
    for(i=0;i<t.length;i++)
     if (t.substr(i,1)=="^")
      {
       jz=parsefind(t,i,-1);
       k=parsefind(t,i,1);
       t=t.substring(0,jz+1)+"Math.pow("+ t.substring(jz+1,i)+","+t.substring(i+1,k)+")"+ t.substring(k,t.length);
       n++;
       if(n>15)
       break;
      }

   if(t=="")
    return "(0)";

   if(t==null)
    return;

   var tt=t;

   t=t.replace(/\+/g,"+");
   t=t.replace(/\-/g,"-");
   t=t.replace(/\—/g,"-");
   t=t.replace(/\–/g,"-");
   t=t.replace(/\·/g,"*");
   t=t.replace(/\*/g,"*");
   t=t.replace(/\//g,"/");

   t=t.replace(/ \^ /g,"^");

        t=t.replace(/x/g,"X").replace(/y/g,"Y");

        if (t=="")
         t="0";
        return t.substr(1,t.length-2);
}

// -------------------------------------------------------

function parsefind(t,iz,r)
{
var L_=t.length, k=0, jz=0;
for(jz=iz+r;(jz<L_)&&(jz>=0);jz+=r)
{
var u=t.substr(jz,1);
if(u=="(")k++; else if(u==")")k--;
if(k*r<0)return jz;
if((k==0)&&((u=="+")||(u=="-")||(u=="*")||(u=="/")||(u==";")||(u==",")||(u=="=")||(u=="\"")||(u=="'")||(u=="|")||(jz+r==L_+1)||(jz+r==-1))) return jz;
}
return jz;
}

// --------------------------------------------------

function ggT(a,b)
 {
  var c;
  if((isNaN(a))||(isNaN(b)))
    return 1;

  if(((a%1)!=0)||((b%1)!=0))
    return 1;

  a=Number(a);
  b=Number(b);

  if (a*b == 0)
    return 1;

  do
   {
    c = a%b;
    a = b;
    b = c;
   }
  while (c != 0);
  return a;
}

// ------------------------------------------------------------------------------

// verwandelt dezimalzahl in einen bruch
function dez_to_bruch_1(d)   // erwartet zahl
 {
  var a2, a1, a0, b2, b1, b0, aa;
  var b, bb, B;
  var c;
  var m=1;
  var neg=false, nm=1, nn = 1000 ;   // nn max nenner
  var q;
  var r, rr;
  var t="";
  var zm=1;

   if( d < 0 )
      {
      neg = true;
      d = Math.abs(d);
      }

  b=GetBruch2a(d);    // b ist ein string z.B. 1/5

  if(String(b).indexOf("/")==-1)
    {
     t+=b+"/1\t = "+b+"\r\n";
     nm=1;
     zm=b;
     m=0;

     if (neg)
       return "- "+zm;

     return zm;
    }

   B=b.split("/"), r=Number(B[1]),q=Number(B[0]);
   rr=q%r,c=r;
   q=Math.floor(q/r);
   r=rr;
   a2=0,a1=1,a0=q,b2=1,b1=0,b0=1;
   while(b0<=nn)
      {
        t+=a0+"/"+b0+"\t = "+(a0/b0)+"\r\n";
        q=Math.floor(c/r);
        rr=c%r;
        c=r;
        r=rr;
        aa=q*a0+a1;
        a2=a1;
        a1=a0;
        a0=aa;
        bb=q*b0+b1;
        b2=b1;
        b1=b0;
        b0=bb;
      }
  nm=b1;
  zm=a1;
  m=Math.abs(d-zm/nm);

  if (neg)
     return "- "+zm+"/"+nm;

  return zm+"/"+nm;
 }

//---------------------------------------------------------------

function GetBruch2a(x)
{
  var ggt, iz, n, t, z;

  x=x.toFixed(12);
  t=String(x);
  iz=t.indexOf(".");
  if(iz==-1) return x;
  if((t.length-iz>20)||(t.length>25)) return "";

  z=Number(t.substring(0,iz)+t.substring(iz+1,t.length));
  n=Number(1+"00000000000000000000000000000000000000".substr(0,t.length-iz-1));
  ggt=ggT(z,n);
  //alert("x = "+x+"\n t = "+t+"\n i = "+i+"\n z = "+z+"\n n = "+n+"\n ggt = "+ggt+"\n returnwert = "+z/ggt+"/"+n/ggt);

  if( n/ggt == 1 )
  return z/ggt;

  return z/ggt+"/"+n/ggt;

}

//-----------------------------------------------------------------

function cpik(zahl)
// wandelt Zahl in String und ersetzt Dezimalpunkt durch Komma
// Rückgabewert: Zahlenstring
// z.B. 4.15 -- 4,15
 {
   var zs="", p=0, k=",";
   zs = String(zahl);
   p = zs.indexOf('.');
   if ( p != -1)
      {
        zs = zs.substring(0,p)+k+zs.substring(p+1,zs.length);
      }
   return zs;
 }

// ---------------------------------------------------------------------- //

function cut_nk(ptext)
// entfernt aus einem String das Komma und alle Nullen danach
// z.B. 2,000 -- 2 aber 2,001 -- 2,001
 {
  var i, unfertig=true;
  for ( i=ptext.length-1; i >=ptext.indexOf(",") && unfertig; i-- )
   {
     if( ptext.substring(i,i+1) == "0" )
       {
        ptext=ptext.substring(0,i);
        //alert("text= "+i+"="+ptext);
       }
    else
      {
       unfertig=false;
       //alert("fertigtext= "+i+"="+ptext);
      }
    }

  if ( ptext.substring(ptext.length-1,ptext.length) == ",")
     {
       ptext=ptext.substring(0,ptext.length-1);
       //alert("fertigtext ohne komma= "+ptext);
     }
   return ptext;
 }

// ---------------------------------------------------------------------- //

// In einem String wird gesucht und ersetzt
function suche_ersetze(suchtext,suche,ersetze)
 {
  var re=new RegExp(suche,"g");
  return suchtext.replace(re,ersetze);
 }

// ---------------------------------------------------------------------- //


// formatiert alle Koeffaizienten für form_fkt_gl()
function k_x(kf,flag)
 {
  var bruch1=false;

  if (flag == "1")
     bruch1 = true;

  if ( kf.toFixed(4) ==  1 ) return " + ";
  if ( kf.toFixed(4) == -1 ) return " - ";

  if(bruch1)
   {
     if( kf.toFixed(4) < 0 && kf.toFixed(4) != -1 ) return " - "+dez_to_bruch_1(Math.abs(kf));
     if( kf.toFixed(4) > 0 && kf.toFixed(4) !=  1 ) return " + "+dez_to_bruch_1(kf);
     return "0";
   }
  else
   {
     if( kf.toFixed(4) < 0 && kf.toFixed(4) != -1 ) return " - "+cut_nk(cpik(Math.abs(kf).toFixed(nks)));
     if( kf.toFixed(4) > 0 && kf.toFixed(4) !=  1 ) return " + "+cut_nk(cpik(kf.toFixed(nks)));
     return "0";
   }
 }

// ---------------------------------------------------------------------- //

function form_fkt_gl(flag)  // formatiert die Funktionsgleichung
 {
   var i;
   var text=new Array();
   var ptext="",nullenz=0;

   var bruch1=false;

  if (flag == "1")
     bruch1 = true;

   var ai=new Array();
   var ttext="";

   for( i=0; i<=kmax; i++)
    {
     ai[i]="";
    }

   for( i=0; i<=kmax; i++)
    {
     ai[i]=k_x(a[i],flag);
    }

   for( i=0; i<=kmax; i++)  // zählt alle Nullkoeffizienten
    {
      if( a[i] == 0 )
        {
          nullenz=nullenz+1;
        }
    }

   //alert(nullenz);

  if( nullenz != kmax+1 )     // nicht alles ist Null
    {

     for( i=0; i<=kmax; i++)
      {
       if( ai[kmax-i] != "0")
         ttext=ttext+ai[kmax-i]+"x<sup>"+(kmax-i)+"</sup>";
      }

      ttext=suche_ersetze(ttext,"x<sup>"+1+"</sup>","x");   // x hoch 1 durch x ersetzen
      ttext=suche_ersetze(ttext," x<sup>"+0+"</sup>"," 1");  // _x hoch Null durch _1 ersetzen
      ttext=suche_ersetze(ttext,"x<sup>"+0+"</sup>","");     //  ax hoch 0 durch a ersetzen

      if ( ttext.indexOf("+") == 1 )
        {
         ttext = ttext.slice(2);  // die ersten beiden Zeichen hier +_ entfernen
        }
    return ttext;
   }
   else
   {
     ttext = "0";
     return ttext;
   }
 }

 // ---------------------------------------------------------------------- //

// formatiert Koeffizienten
function k_f(kf,wo,flag)
 {
  var bruch1=false;

  if (flag == "1")
     bruch1 = true;

  if(wo=="k")   // für koeffizienten und koordinaten
   {
     if ( kf.toFixed(4) ==  1 ) return "1";
     if ( kf.toFixed(4) == -1 ) return "-1";
     if ( kf.toFixed(4) ==  0 ) return "0";
     if (bruch1)
     {
     if ( kf.toFixed(4) > 0 && kf.toFixed(4) !=  1 ) return dez_to_bruch_1(kf);
     if ( kf.toFixed(4) < 0 && kf.toFixed(4) != -1 ) return "-"+dez_to_bruch_1(Math.abs(kf));
     }
    else
     {
      if ( kf.toFixed(4) > 0 && kf.toFixed(4) !=  1 ) return cut_nk(cpik(kf.toFixed(nks)));
      if ( kf.toFixed(4) < 0 && kf.toFixed(4) != -1 ) return "-"+cut_nk(cpik(Math.abs(kf).toFixed(nks)));
     }
   }

  if ( kf.toFixed(4) ==  0 ) return "";

  if(wo=="a") // erster koeffizient für funktionsterm
   {
    if ( kf.toFixed(4) ==  1 ) return "";
    if ( kf.toFixed(4) == -1 ) return " - ";
    if (bruch1)
     {
     if ( kf.toFixed(4) < 0 && kf.toFixed(4) != -1 ) return " -"+dez_to_bruch_1(Math.abs(kf));
     if ( kf.toFixed(4) > 0 && kf.toFixed(4) !=  1 ) return dez_to_bruch_1(kf);
     }
    else
     {
      if ( kf.toFixed(4) < 0 && kf.toFixed(4) != -1 ) return " -"+cut_nk(cpik(Math.abs(kf).toFixed(nks)));
      if ( kf.toFixed(4) > 0 && kf.toFixed(4) !=  1 ) return cut_nk(cpik(kf.toFixed(nks)));
     }
   }

  if(wo=="m")  // mittlerer koeffizient für funktionsterm
   {
    if ( kf.toFixed(4) ==  1 ) return " + ";
    if ( kf.toFixed(4) == -1 ) return " - ";
    if (bruch1)
     {
     if ( kf.toFixed(4) < 0 && kf.toFixed(4) != -1 ) return " - "+dez_to_bruch_1(Math.abs(kf));
     if ( kf.toFixed(4) > 0 && kf.toFixed(4) !=  1 ) return " + "+dez_to_bruch_1(kf);
     }
    else
     {
      if ( kf.toFixed(4) < 0 && kf.toFixed(4) != -1 ) return " - "+cut_nk(cpik(Math.abs(kf).toFixed(nks)));
      if ( kf.toFixed(4) > 0 && kf.toFixed(4) !=  1 ) return " + "+cut_nk(cpik(kf.toFixed(nks)));
     }
   }

  if(wo=="e") // letzter koeffizient für funktionsterm
   {
    if ( kf.toFixed(4) ==  1 ) return " + 1";
    if ( kf.toFixed(4) == -1 ) return " - 1";
    if (bruch1)
     {
     if ( kf.toFixed(4) < 0 && kf.toFixed(4) != -1 ) return " - "+dez_to_bruch_1(Math.abs(kf));
     if ( kf.toFixed(4) > 0 && kf.toFixed(4) !=  1 ) return " + "+dez_to_bruch_1(kf);
     }
    else
     {
      if ( kf.toFixed(4) < 0 && kf.toFixed(4) != -1 ) return " - "+cut_nk(cpik(Math.abs(kf).toFixed(nks)));
      if ( kf.toFixed(4) > 0 && kf.toFixed(4) !=  1 ) return " + "+cut_nk(cpik(kf.toFixed(nks)));
     }
   }

 }

// ---------------------------------------------------------------------- //

 function klammertest(t)   // testet Klammerausdrücke
 {
   var i;
   for( i = 0 ; i < t.length ; i++ )
    {
      if( (t.charAt(i) != "(") && (t.charAt(i) != ")") )

        {
         t = t.substr(0,i)+" "+t.substring(i+1,t.length);
        }
    }

      t = t.replace(/ /g,"");  // ersetzt nix durch ""

      do
       {
         t=t.replace(/\(\)/,"");  // ersetzt () durch ""
       }
      while(t.indexOf("()") > -1);

     return (t=="");
 }

 //-----------------------------------------------------------------

 function fkt(x)
 {
  // ersetzt den String X in f_str durch ( xwert ) und liefert den Funktionswert zurück
  // f_str ist global definiert
  return eval(f_str.replace(/X/g,"("+x+")"));
 }


 //-------------------------------------------------------------------------------


 function fkt_plotter()
{

kx=new Array(); // x-Koordinaten
ky=new Array(); // y-Koordinaten

var i;
var tx,ty,zx,zy;   // Variablen für Beschriftungszahlen

for (i = xa; i < xe; i++)
  {
    // x-Werte im Bereich von -xe/2<=x<=xe festlegen (Definitionsmenge)
    x[i]=(-xe/2+i)/kga; // für diese x-Werte werden Funktionswerte berechnet (extern)
    // x-Koordinaten für Zeichenfläche absolut xa<=x<=xe
    kx[i]=i;
  }

  // Funktionswerte (y-Werte) werden berechnet (extern)
   funktionswerte();

 for (i = xa; i <= xe; i++)
  {
    // y-Koordinaten belegen vom Koordinatenursprung aus
    ky[i]=Math.round( y0-(y[i])/ysf );
    // -----------------------------
    if ( Math.round(ky[i])<ya)
       ky[i]=ya;
    if ( Math.round(ky[i])>ye)
       ky[i]=ye;
    // ----------------------------
  }



if(!grid)
{
// Koordinatengitter im Abstand von kga px
jg.setColor("00ffcc"); // hellblau

for (i = xa; i <= xe/kga; i++)
  {
    jg.drawLine(xa+kga*i, ya, xa+kga*i, ye); // senkrecht
  }

for (i = ya; i <= ye/kga; i++)
  {
    jg.drawLine(xa, ya+kga*i, xe, ya+kga*i); // waagerecht
  }

jg.setColor("000099"); // dunkelblau
jg.drawLine(xa, ya+ye/2, xe, ya+ye/2); // zeichnet die x-Achse
jg.drawLine(xa+xe/2, ya, xa+xe/2, ye); // zeichnet die y-Achse

jg.setFont("arial","8px");  // Schrift für die Koordinatenwerte

for (i = xa; i < xe/kga-1; i++)
  {
    zx=(-xe/kga)/2+1+i;
    tx=zx.toString();
    jg.drawString(tx,-2+kga*(i+1),y0+3);  // Beschriftung der x-Achse
    jg.drawLine(xa+kga*(i+1), y0, xa+kga*(i+1), y0+2);  //Markierung der x-Achse
  }

for (i = ya; i < ye/kga-1; i++)
  {
    zy=ysf*((ye/kga)/2-1-i);
    ty=zy.toString();
    if( ty.substring(0,1) =='-')
      {
        ty=ty.substring(0,4);
      }
    else
      {
        ty=ty.substring(0,3);
      }
    jg.drawString(ty,x0-16,-4+kga*(i+1));   // Beschriftung der y-Achse
    jg.drawLine(x0-2,ya+kga*(i+1),x0, ya+kga*(i+1));  //Markierung der y-Achse
  }

  // Pfeilspitze der x-Achse
  jg.drawLine(xe-4,y0-2,xe,y0);
  jg.drawLine(xe-4,y0+2,xe,y0);

  // Pfeilspitze der y-Achse
  jg.drawLine(xe/2-2,ya+4,xe/2,ya);
  jg.drawLine(xe/2+2,ya+4,xe/2,ya);

  jg.setFont("arial","10px");      // Schriftgröße für die Achsenbezeichnung
  jg.drawString("x",xe-7,y0+1);    // Beschriftung der x-Achse mit x
  jg.drawString("y",x0-10,ya);     // Beschriftung der y-Achse mit y

  grid=true;
}

jg.setColor(plotfarbe); // rot
for (i = xa; i <= xe; i++)
  {
  if ( ky[i]>ya && ky[i]<ye )

    {
    jg.drawLine(kx[i],ky[i],kx[i+1],ky[i+1]);   // Graph intern zeichnen

    }
  }

jg.setColor(punktfarbe); // dunkelblau
if ( punkte )
  {
   for (i = 1; i <= paz; i++)
    {
      if ( Math.round(y0-((kga*ypi[i])/ysf)-2)>ya && Math.ceil(y0-((kga*ypi[i])/ysf)-2)<=ye)
        {
          jg.fillEllipse(x0+(kga*xpi[i])-2,y0-((kga*ypi[i])/ysf)-2,5,5);
        }
    }
  }



jg.paint();  // Ausgabe ins Dokument


}

//--------------------------------------------------------------------------------

 function fkt_plotter1()
{

kx=new Array(); // x-Koordinaten
ky=new Array(); // y-Koordinaten

var tx,ty,zx,zy;   // Variablen für Beschriftungszahlen
var i;

for (i = xa; i < xe; i++)
  {
    // x-Werte im Bereich von -xe/2<=x<=xe festlegen (Definitionsmenge)
    x[i]=(-xe/2+i)/kga; // für diese x-Werte werden Funktionswerte berechnet (extern)
    // x-Koordinaten für Zeichenfläche absolut xa<=x<=xe
    kx[i]=i;
  }

  // Funktionswerte (y-Werte) werden berechnet (extern)
   funktionswerte();

 for (i = xa; i <= xe; i++)
  {
    // y-Koordinaten belegen vom Koordinatenursprung aus
    ky[i]=Math.round( y0-(y[i])/ysf );
    // -----------------------------
    if ( Math.round(ky[i])<ya)
       ky[i]=ya;
    if ( Math.round(ky[i])>ye)
       ky[i]=ye;
    // ----------------------------
  }



if(!grid)
{
// Koordinatengitter im Abstand von kga px
jg1.setColor("00ffcc"); // hellblau

for (i = xa; i <= xe/kga; i++)
  {
    jg1.drawLine(xa+kga*i, ya, xa+kga*i, ye); // senkrecht
  }

for (i = ya; i <= ye/kga; i++)
  {
    jg1.drawLine(xa, ya+kga*i, xe, ya+kga*i); // waagerecht
  }

jg1.setColor("000099"); // dunkelblau
jg1.drawLine(xa, ya+ye/2, xe, ya+ye/2); // zeichnet die x-Achse
jg1.drawLine(xa+xe/2, ya, xa+xe/2, ye); // zeichnet die y-Achse

jg1.setFont("arial","8px");  // Schrift für die Koordinatenwerte

for (i = xa; i < xe/kga-1; i++)
  {
    zx=(-xe/kga)/2+1+i;
    tx=zx.toString();
    jg1.drawString(tx,-2+kga*(i+1),y0+3);  // Beschriftung der x-Achse
    jg1.drawLine(xa+kga*(i+1), y0, xa+kga*(i+1), y0+2);  //Markierung der x-Achse
  }

for (i = ya; i < ye/kga-1; i++)
  {
    zy=ysf*((ye/kga)/2-1-i);
    ty=zy.toString();
    if( ty.substring(0,1) =='-')
      {
        ty=ty.substring(0,4);
      }
    else
      {
        ty=ty.substring(0,3);
      }
    jg1.drawString(ty,x0-16,-4+kga*(i+1));   // Beschriftung der y-Achse
    jg1.drawLine(x0-2,ya+kga*(i+1),x0, ya+kga*(i+1));  //Markierung der y-Achse
  }

  // Pfeilspitze der x-Achse
  jg1.drawLine(xe-4,y0-2,xe,y0);
  jg1.drawLine(xe-4,y0+2,xe,y0);

  // Pfeilspitze der y-Achse
  jg1.drawLine(xe/2-2,ya+4,xe/2,ya);
  jg1.drawLine(xe/2+2,ya+4,xe/2,ya);

  jg1.setFont("arial","10px");      // Schriftgröße für die Achsenbezeichnung
  jg1.drawString("x",xe-7,y0+1);    // Beschriftung der x-Achse mit x
  jg1.drawString("y",x0-10,ya);     // Beschriftung der y-Achse mit y

  // Legende
  jg1.setColor("cc0000");               // rot
  jg1.setFont("arial","10px");          // Schrift für Text
  jg1.drawString("Ausgangsfunktion f(x)",4,4);  // Text
  jg1.setColor("008000");               // grün
  jg1.drawString("1. Ableitung",4,14);  // Text
  jg1.setColor("808000");               // kaki
  jg1.drawString("2. Ableitung",4,24);  // Text
  jg1.setColor("800080");               // lila
  jg1.drawString("3. Ableitung",4,34);  // Text
  jg1.setColor("ffa500");               // orange
  jg1.drawString("Tangenten",4,44);     // Text

  grid=true;
}

jg1.setColor(plotfarbe); // rot
for (i = xa; i <= xe; i++)
  {
  if ( ky[i]>ya && ky[i]<ye )

    {
    jg1.drawLine(kx[i],ky[i],kx[i+1],ky[i+1]);   // Graph intern zeichnen

    }
  }

jg1.setColor(punktfarbe); // dunkelblau
if ( punkte )
  {
   for (i = 1; i <= paz; i++)
    {
      if ( Math.round(y0-((kga*ypi[i])/ysf)-2)>ya && Math.ceil(y0-((kga*ypi[i])/ysf)-2)<=ye)
        {
          jg1.fillEllipse(x0+(kga*xpi[i])-2,y0-((kga*ypi[i])/ysf)-2,5,5);
        }
    }
  }

jg1.paint();  // Ausgabe ins Dokument

}
