import java.util.Scanner;
import java.util.ArrayList;
public class Main
{
public static void main (String[]args)
{
Scanner inp = new Scanner (System.in);
System.out.
println ("This program approximates the Riemann zeta function");
System.out.
println ("through straightforward summation and Euler product");
System.out.print ("\nNumber of terms: ");
int terms = inp.nextInt ();
System.out.print ("Zeta input: ");
double s = inp.nextDouble ();
zeta (terms, s);
}
public static void zeta (int terms, double s)
{
double x = summation (terms, s);
double y = eulerProduct (terms, s);
System.out.println ("\nThrough summation:\tZ(" + s + ") = " + x);
System.out.println ("Through Euler product:\tZ(" + s + ") = " + y);
System.out.println ("Error of Euler product:\t" + error (y, x));
}
public static double summation (int terms, double s)
{
double sum = 0;
for (int n = 1; n <= terms; n++)
{
sum += Math.pow (n, -s);
}
return sum;
}
public static double eulerProduct (int terms, double s)
{
double product = 1;
ArrayList < Integer > primes = new ArrayList < Integer > ();
primes = (ArrayList < Integer >) getPrimes (terms).clone ();
for (int p:primes)
{
product *= Math.pow (p, s) / (Math.pow (p, s) - 1);
}
return product;
}
public static ArrayList < Integer > getPrimes (int terms)
{
ArrayList < Integer > primes = new ArrayList < Integer > ();
primes.add (2);
int i = 1, natural = 2, factors = 0;
while (i < terms)
{
natural++;
factors = 0;
for (int p:primes)
{
if (natural % p == 0)
{
factors++;
break;
}
}
if (factors == 0)
{
primes.add (natural);
i++;
}
}
return primes;
}
public static String error (double observed, double expected)
{
String rtn = "";
double err = observed / expected - 1;
int power = (int) Math.log10 (err) - 1;
err /= Math.pow (10, power);
err = Math.round (100 * err) / 100.0;
if (Math.abs (power) > 3)
{
rtn = err + " * 10 ^ " + (power - 2);
}
else
{
rtn = err * Math.pow (10, power + 2) + "";
}
return rtn + " %";
}
}