#
# Questo programma calcola l'integrale di una funzione
# con i metodi del trapezio, di Simpson e di Gauss
#

def f(x)
   # qui va la funzione da integrare
   return x**3-x**6;
end

# in Ruby non si può passare una funzione come parametro
def integraleTrapezio(xmin,xmax,n)

   # intervallo tra due punti
   h=(xmax-xmin)/n;

   # n deve essere dispari e if può essere postfisso
   n = n+1 if n.even?

   # l'integrale e' una somma, all'inizio va azzerato
   sum=0.0

   for j in 0..n
     # calcolo l'ascissa del punto
     x=xmin+j*h
     # valuto la funzione e la aggiungo all'integrale
     if j==0 or j==n
       sum += 0.5*f(x)
     else
       sum += f(x)
     end
   end
   sum = sum*h;

   return sum;

end

def integraleSimpson(xmin,xmax,n)

   # mi assicuro che n sia dispari
   if n%2==0
     n = n+1
   end

   # intervallo tra due punti in cui valuto la funzione
   h=(xmax-xmin)/n.to_f

   # sommo i termini pari
   sum1=0.0
   for j in (0..n).step(2)
      x=xmin+j*h
      sum1 += f(x)
   end

   # sommo i termini dispari
   sum2=0.0
   for j in (1..n).step(2)
      x=xmin+j*h
      sum2=sum2+f(x)
   end

   # sottraggo 1/3 degli estremi e moltiplico per h
   sum=h*(2.0/3.0*sum1+4.0/3.0*sum2-1.0/3.0*(f(xmin)+f(xmax)))

   return sum
end

def integraleGauss10(xmin,xmax)

    # ascisse e pesi sono tabulati, non e' necessario calcolarli
    # le ascisse sono antisimmetriche i pesi simmetrici

    # ascisse
    y=[0.0,
   0.1488743389,\
   0.4333953941,\
   0.6794095682,\
   0.8650633666,\
   0.9739065285,\
   -0.9739065285,\
   -0.8650633666,\
   -0.6794095682,\
   -0.4333953941,\
   -0.1488743389]

    # pesi
    w = [0,
   0.2955242247,\
   0.2692667193,\
   0.2190863625,\
   0.1494513491,\
   0.0666713443,\
   0.0666713443,\
   0.1494513491,\
   0.2190863625,\
   0.2692667193,\
   0.2955242247];

   somma=0.0;
    # cambio di variabili per integrare tra a e b
    # invece che tar 0 e 1
   for j in 1..10
      x=0.5*(xmax+xmin)+0.5*(xmax-xmin)*y[j]
      somma=somma+w[j]*f(x)
   end

   somma = (xmax-xmin)/2.0*somma

   return somma

end

def main()

   puts integraleTrapezio(0.0,1.0,500).to_s
   puts integraleSimpson(0.0,1.0,500).to_s
   puts integraleGauss10(0.0,1.0).to_s

end

main
