[EDIT] #Ryan Thanks for the solution! However, now I am receiving the error "c defined in first method" when I did not redefine it in the second.
public class cf {
public static void methodOne (double c, double f) {
double c = 40;
double f;
System.out.println("Celsius Fahrenheit");
while (c >= 30) {
f = c * 9/5 +32;
System.out.println((c) + " "+Math.round(f*100.0)/100.0);
c--;
}
}
public static void methodTwo (double ce, double fa) {
double ce;
double fa = 120;
System.out.println("Fahrenheit Celsius");
while (fa >= 30) {
ce = fa * 5/9 -32;
System.out.println((fa) + " "+Math.round(ce*100.0)/100.0);
fa--;
}
}
}
Your root problem is obviously that the conversion from Celsius to Fahrenheit is implemented incorrectly within the loop. I would approach this problem by extracting the "beef" of your application, i.e. the temperature conversion (formula of which is in Wikipedia), into a method of its own:
/**
* Converts the input Celsius temperature into Fahrenheit degrees, using the
* formula:
*
* <pre>
* (degreesCelsius * 1.8) + 32 = degreesFahrenheit
* </pre>
*
* #param degreesCelsius
* temperature in Celsius degrees
* #return the temperature in Fahrenheit degrees
*/
private static float celsiusToFahrenheit(float degreesCelsius) {
return (degreesCelsius * 1.8f) + 32.0f;
}
You should separate the calculation from the rest of the code because it:
Improves the readability of your code
Separates the concerns of iterating a range and calculating the conversion, which in turn makes
your application modular
implementing changes simpler
testing the conversion simpler
reusing the conversion possible
After you have done the above, the rest of the code only handles the initialization of the range and iterating over it:
// define the range
final int cMin = 30;
final int cMax = 40;
// run the conversion
for (int i = cMax; i >= cMin; i--) {
float degreesCelsius = (float) i;
float degreesFahrenheit = celsiusToFahrenheit(degreesCelsius);
System.out.println(String.format("%.1f\t|\t%.1f", degreesCelsius,
degreesFahrenheit));
}
Note that I've declared the Celsius degree range as ints because the requirement was an increment of one degree between each conversion. The values are cast into floats before the calculation.
You should avoid magic numbers in your code, which is why the range is defined as a pair of final variables (which you could also parse out from the args array, if you want to accept user input). The range could also be defined as static final fields if you don't expect it to change between runs of the program.
Finally, utility class Formatter is used for outputting the data through String.format(). This makes it easy to change the precision of the float values in the output.
public static void main(String[] args) {
double c=40;
double f;
while(c >= 30){
f = c * 9/5 +32; //°C x 9/5 + 32 = °F
System.out.println(c + "|" + f);
c--;
}
}
This should do it.
System.out.println(String.format("%-10s %-10s","Celsius ","Fahrenheit"));
double f = 30;
double c;
double i = 1;
while (f <= 120) {
f += i * 1 + f;
c = (5.0 / 9.0) * (f - 32);
System.out.println(String.format("%-10s %-10s",(double) Math.round((c / c * 100) * 10) / 10,(double) Math.round((f / f * 100) * 10) / 10));
i++;
}
This will format your code how you like it. It will give you your output as requested.
public class Far {
public static void main(String[] args) {
double c = 40;
double f;
System.out.println("Celsius Fahrenheit");
while (c >= 30) {
f = c * 9/5 +32;
System.out.println((c) + " "+Math.round(f*100.0)/100.0);
c--;
}
}
}
Related
This question already has answers here:
What is a NumberFormatException and how can I fix it?
(9 answers)
Closed 3 years ago.
import java.text.NumberFormat;
public class Mortgage {
public static void main(String[] args) {
int p = 1000000;
NumberFormat percent = NumberFormat.getPercentInstance();
double r = Double.parseDouble(percent.format(3.92*12));
int t = (int)(r);
double n;
n = Math.pow(30,12);
int f = (int) Math.floor(n);
int a =(1+t)^f;
int b = (a-1);
int c = (t*a)/b;
int m = p*c;
NumberFormat currency = NumberFormat.getCurrencyInstance();
String result = currency.format(m);
System.out.println(result);
}
}
I have tried to changed r to int but I still got exception. What am I not writing correctly?
You use NumberFormat.getPercentInstance() to format your number. This adds a % symbol and other number formatting (depending on your default locale). Then the Double.parseDouble(...) call fails because the number is not a pure double number.
There is no need to format and parse the number, you can just assign it directly to the double variable as it is a constant anyways.
I see several problems.
double n;
n = Math.pow(30,12);
int f = (int) Math.floor(n);
30 to the 12th power. That does not make sense for a 30 year mortgage Did you mean 30*12 for 360 pay periods. Or possibly Math.pow(30,1+montlyRate) where monthlyRate = (AR/100)/12 and AR = annual rate).
int a =(1+t)^f;
The operator ^ is not power but an exclusive OR. You probably didn't want that either.
I recommend you check out this Wiki entry on computing Mortage Payments
Here is one way to do calculate it and then display it per month.
double in = 5.5; // annual percentage rate
double mo_rate = (in / 100) / 12.; // monthly rate
double PV = 400_000.; // present value (cost of the house).
double f = Math.pow(1 + mo_rate, 360); // factor resulting from the linear
// expansion
double payment = mo_rate * PV * f / (f - 1); // Monthly payment including
// interest and
// principal
System.out.printf("Monthly payment is %7.2f%n", payment);
Note: different banks and/or countries may do it differently.
The answer is in the exception java.lang.NumberFormatException: For input string: "4,704%"
percent.format(3.92*12) returns the String : 4 704 % and this can't be parsed to double, because of the space and the % symbol, you just need to multiply it by 100 to consider it as a percentage
double r = 3.92 * 12 * 100;
As you're using only ints you fall into the int division problem and you'll get a 0 at the end, so you may use at leat one double ot cast one durint the division
int a = (1 + t) ^ f;
double b = (a - 1);
double c = (t * a) / b;
double m = p * c;
// OR
int a = (1 + t) ^ f;
int b = (a - 1);
double c = (t * a) / (double) b;
double m = p * c;
Also ^ is thr XOR symbol, to use power computation :
double a = Math.pow(1+t, f);
For the result, it depends on r:
double r = 3.92 * 12 * 100; gives -10 308,38 €
double r = 3.92 * 12; gives 999 998,95 €
And use names that explain what the variable is, as much as possible
How to make the method roots check imaginary roots and real one then return their values?
package warmup;
import java.util.HashSet;
import java.util.Set;
public class Quadratic {
/**
* Find the integer roots of a quadratic equation, ax^2 + bx + c = 0.
* #param a coefficient of x^2
* #param b coefficient of x
* #param c constant term. Requires that a, b, and c are not ALL zero.
* #return all integers x such that ax^2 + bx + c = 0.
*/
public static Set<Integer> roots(int a, int b, int c) {
Set<Integer> z = new HashSet<>();
int temp1 = (int)(Math.sqrt(b*b - 4*a*c));
if(a !=0){
if(temp1 >= 0){
Integer x1 = (int) ((-b + temp1) / (2*a));
Integer x2 = (int) ((-b - temp1) / (2*a));
z.add(x1);
z.add(x2);
} else if (temp1 < 0){
Integer x1 = (int) ((-b + temp1) / (2*a));
Integer x2 = (int) ((-b - temp1) / (2*a));
z.add(x1);
z.add(x2);
}
}else{
System.out.println("Error: division by zero.");
}
return z;
}
/**
* Main function of program.
* #param args command-line arguments
*/
public static void main(String[] args) {
System.out.println("For the equation x^2 - 4x + 3 = 0, the possible solutions are:");
Set<Integer> result = roots(1, -4, 3);
System.out.println(result);
}
trying to assign a negative square root number value to java is not allowed in JDK.
what you can do is, you can create a complex number class of your own and do your own operations there. Here is the example which i found online:
http://introcs.cs.princeton.edu/java/97data/Complex.java.html
I also looked at SO for similar questions like yours and i got this link
Hope this helps
If you are unsure of what "Poisson Distrubtion using Normal Approximation" means, follow this link and check the texts inside the yellow box.
https://onlinecourses.science.psu.edu/stat414/node/180
Here, is the simple snapshot of the math from the link.
P(Y≥9) = P(Y>8.5) = P(Z>(8.5−6.5)/√6.5) = P(Z>0.78)= 0.218
So to get the value in .218, we use Simpson's integration rule which
integrates the function(Implemented in method named "f" from code below) from "negative
infinity" to the value that equals to this >> "((8.5−6.5)/√6.5))"
R successfully gives the correct output. But in Java when i implemented the code
below copied from "http://introcs.cs.princeton.edu/java/93integration/SimpsonsRule.java.html"
I get "0.28360853976343986" which should have been ".218" Is it any how because of the negative infinity value I am using, which is "Double.MIN_VALUE"
This is the code in Java. See at the very end for my INPUTS in the main method.
* Standard normal distribution density function.
* Replace with any sufficiently smooth function.
**********************************************************************/
public static double f(double x) {
return Math.exp(- x * x / 2) / Math.sqrt(2 * Math.PI);
}
/**********************************************************************
* Integrate f from a to b using Simpson's rule.
* Increase N for more precision.
**********************************************************************/
public static double integrate(double a, double b) {
int N = 10000; // precision parameter
double h = (b - a) / (N - 1); // step size
// 1/3 terms
double sum = 1.0 / 3.0 * (f(a) + f(b));
// 4/3 terms
for (int i = 1; i < N - 1; i += 2) {
double x = a + h * i;
sum += 4.0 / 3.0 * f(x);
}
// 2/3 terms
for (int i = 2; i < N - 1; i += 2) {
double x = a + h * i;
sum += 2.0 / 3.0 * f(x);
}
return sum * h;
}
// sample client program
public static void main(String[] args) {
double z = (8.5-6.5)/Math.sqrt(6.5);
double a = Double.MIN_VALUE;
double b = z;
System.out.println(integrate(a, b));
}
Anybody has any ideas? I tried using Apache math's "PoissonDistribution" class's method "normalApproximateProbability(int x)". But the problem is this method takes an "int".
Anyone has any better ideas on how do I get the correct output or any other code. I have used another library for simpson too but I get the same output.
I need this to be done in Java.
I tried to test the code by writing another method that implements Simpson's 3/8 rule instead of your integrate function. It gave the same result as the one you obtained at first time. So i think the difference arises most probably from rounding errors.
(Note: I found a partial solution. I have pasted the test results at the end)
I am looking to numerically integrate an approximation of the zeta function. This is done through what is known as the Abel-Plana formula. The Abel-Plana formula can be used to numerically evaluate Zeta(s) for s = a + i*b.
I first wrote a program to calculate Zeta(s) for s in real. It seems to work,
/**************************************************************************
**
** Abel-Plana Formula for the Zeta Function
**
**************************************************************************
** Axion004
** 08/16/2015
**
** This program computes the value for Zeta(s) using a definite integral
** approximation through the Abel-Plana formula. The Abel-Plana formula
** can be shown to approximate the value for Zeta(s) through a definite
** integral. The integral approximation is handled through the Composite
** Simpson's Rule known as Adaptive Quadrature.
**************************************************************************/
import java.util.*;
import java.math.*;
public class AbelMain2 {
public static void main(String[] args) {
AbelMain();
}
public static void AbelMain() {
double s = 0;
double start, stop, totalTime;
Scanner scan = new Scanner(System.in);
System.out.print("Enter the value of s inside the Riemann Zeta " +
"Function: ");
try {
s = scan.nextDouble();
}
catch (Exception e) {
System.out.println("Please enter a valid number for s.");
}
start = System.currentTimeMillis();
System.out.println("The value for Zeta(s) is " + AbelPlana(s));
stop = System.currentTimeMillis();
totalTime = (double) (stop-start) / 1000.0;
System.out.println("Total time taken is " + totalTime + " seconds.");
}
// The definite integral for Zeta(s) in the Abel Plana formula.
// Numerator = Sin(s * arctan(t))
// Denominator = (1 + t^2)^(s/2) * (e^(pi*t) + 1)
public static double function(double x, double s) {
double num = Math.sin(s * Math.atan(x));
double den = Math.pow((1.0 + Math.pow(x, 2.0)), s / 2.0) *
(Math.pow(Math.E, Math.PI * x) + 1.0);
return num / den;
}
// Adaptive quadrature - See http://www.mathworks.com/moler/quad.pdf
// Used to approximate values for definite integrals
// Parameters - a is the start of the integral, b is the end of the
// integral, s is the double value used to evaulate Zeta(s).
public static double adaptiveQuad(double a, double b, double s) {
double EPSILON = 1E-6;
double step = b - a;
double c = (a + b) / 2.0;
double d = (a + c) / 2.0;
double e = (b + c) / 2.0;
double S1 = step / 6.0 * (function(a, s) + 4*function(c, s) +
function(b, s));
double S2 = step / 12.0 * (function(a, s) + 4*function(d, s) +
2*function(c, s) + 4*function(e, s) + function(b, s));
if (Math.abs(S2 - S1) <= EPSILON)
return S2 + (S2 - S1) / 15.0;
else
return adaptiveQuad(a, c, s) + adaptiveQuad(c, b, s);
}
// Returns an approximate sum of Zeta(s) through an integral aproximation
// by Adaptive Quadrature
public static double AbelPlana(double s) {
double C1 = Math.pow(2.0, s - 1.0) / (s - 1.0);
double C2 = Math.pow(2.0, s);
return C1 - C2 *adaptiveQuad(0, 10, s);
}
}
I then tried to extend this program to s in complex. It appears that the program doesn't work because I am trying to numerically evaluate a complex function through quadrature. The quadrature method that I wrote is only applicable to real-value functions as shown in Adaptive Quadrature. The work around I used is rather strange although it seems to work.
Here is what I wrote for the numerical approximation. I had to use a helper class in order to calculate complex numbers in Java.
/**************************************************************************
**
** Abel-Plana Formula for the Zeta Function
**
**************************************************************************
** Axion004
** 08/16/2015
**
** This program computes the value for Zeta(s) using a definite integral
** approximation through the Abel-Plana formula. The Abel-Plana formula
** can be shown to approximate the value for Zeta(s) through a definite
** integral. The integral approximation is handled through the Composite
** Simpson's Rule known as Adaptive Quadrature.
**************************************************************************/
import java.util.*;
import java.math.*;
public class AbelMain extends Complex {
public static void main(String[] args) {
AbelMain();
}
public static void AbelMain() {
double re = 0;
double im = 0;
double start, stop, totalTime;
Scanner scan = new Scanner(System.in);
System.out.println("Calculation of the Riemann Zeta " +
"Function in the form Zeta(s) = a + ib.");
System.out.println();
System.out.print("Enter the value of [a] inside the Riemann Zeta " +
"Function: ");
try {
re = scan.nextDouble();
}
catch (Exception e) {
System.out.println("Please enter a valid number for a.");
}
System.out.print("Enter the value of [b] inside the Riemann Zeta " +
"Function: ");
try {
im = scan.nextDouble();
}
catch (Exception e) {
System.out.println("Please enter a valid number for b.");
}
start = System.currentTimeMillis();
Complex z = new Complex(re, im);
if ( re == 1 && im == 0)
System.out.println("Zeta(s) is undefined for Zeta(1 + 0*i).");
else
System.out.println("The value for Zeta(s) is " + AbelPlana(z));
stop = System.currentTimeMillis();
totalTime = (double) (stop-start) / 1000.0;
System.out.println("Total time taken is " + totalTime + " seconds.");
}
// The definite integral for Zeta(s) in the Abel Plana formula.
// Numerator = Sin(s * arctan(t))
// Denominator = (1 + t^2)^(s/2) * (e^(pi*t) + 1)
public static Complex f(double t, Complex z) {
Complex num = (z.multiply(Math.atan(t))).sin();
Complex D1 = new Complex(1 + t*t, 0).pow(z.divide(2.0));
double D2 = Math.pow(Math.E, Math.PI * t) + 1.0;
Complex den = D1.multiply(D2);
return num.divide(den);
}
// Adaptive quadrature - See http://www.mathworks.com/moler/quad.pdf
// Used to approximate values for definite integrals
// Parameters - a is the start of the integral, b is the end of the
// integral, s is the double value used to evaulate Zeta(s).
public static Complex adaptiveQuad(double a, double b, Complex s) {
double EPSILON = 1E-6;
double step = b - a;
double c = (a + b) / 2.0;
double d = (a + c) / 2.0;
double e = (b + c) / 2.0;
Complex S1 = (f(a, s).add(f(c, s).multiply(4)).add(f(b, s))).
multiply(step / 6.0);
Complex S2 = (f(a, s).add(f(d, s).multiply(4)).add(f(c, s).multiply(2))
.add(f(e, s).multiply(4)).add(f(b, s))).multiply(step / 12.0);
Complex result = (S2.minus(S1)).divide(15.0);
if(S2.minus(S1).mod() <= EPSILON)
return S2.add(result);
else
return adaptiveQuad(a, c, s).add(adaptiveQuad(c, b, s));
}
// Returns an approximate sum of Zeta(s) through an integral aproximation
// by Adaptive Quadrature
public static Complex AbelPlana(Complex z) {
Complex two = new Complex(2.0, 0.0);
Complex C1 = two.pow(z.minus(1.0)).divide(z.minus(1.0));
Complex C2 = two.pow(z);
Complex mult = C2.multiply(adaptiveQuad(0, 10, z));
if ( z.re < 0 && z.re % 2 == 0 && z.im == 0)
return new Complex(0.0, 0.0);
else
return C1.minus(mult);
}
public AbelMain(double re, double im) {
super(re, im);
}
}
The second class for Complex numbers.
/**************************************************************************
**
** Complex Numbers
**
**************************************************************************
** Axion004
** 08/20/2015
**
** This class is necessary as a helper class for the calculation of
** imaginary numbers. The calculation of Zeta(s) inside AbelMain is in
** the form of z = a + i*b.
**************************************************************************/
public class Complex extends Object{
public double re;
public double im;
/**
Constructor for the complex number z = a + i*b
#param re Real part
#param im Imaginary part
*/
public Complex (double re, double im) {
this.re = re;
this.im = im;
}
/**
Real part of the Complex number
#return Re[z] where z = a + i*b.
*/
public double real() {
return re;
}
/**
Imaginary part of the Complex number
#return Im[z] where z = a + i*b.
*/
public double imag() {
return im;
}
/**
Complex conjugate of the Complex number
in which the conjugate of z is z-bar.
#return z-bar where z = a + i*b and z-bar = a - i*b
*/
public Complex conjugate() {
return new Complex(re, -im);
}
/**
Addition of two Complex numbers (z is unchanged).
<br>(a+i*b) + (c+i*d) = (a+c) + i*(b+d)
#param t is the number to add.
#return z+t where z = a+i*b and t = c+i*d
*/
public Complex add(Complex t) {
return new Complex(re + t.real(), im + t.imag());
}
/**
Addition of Complex number and a double.
#param d is the number to add.
#return z+d where z = a+i*b and d = double
*/
public Complex add(double d){
return new Complex(this.re + d, this.im);
}
/**
Subtraction of two Complex numbers (z is unchanged).
<br>(a+i*b) - (c+i*d) = (a-c) + i*(b-d)
#param t is the number to subtract.
#return z-t where z = a+i*b and t = c+i*d
*/
public Complex minus(Complex t) {
return new Complex(re - t.real(), im - t.imag());
}
/**
Subtraction of Complex number and a double.
#param d is the number to subtract.
#return z-d where z = a+i*b and d = double
*/
public Complex minus(double d){
return new Complex(this.re - d, this.im);
}
/**
Complex multiplication (z is unchanged).
<br> (a+i*b) * (c+i*d) = (a*c)+ i(b*c) + i(a*d) - (b*d)
#param t is the number to multiply by.
#return z*t where z = a+i*b and t = c+i*d
*/
public Complex multiply(Complex t) {
return new Complex(re * t.real() - im * t.imag(), re *
t.imag() + im * t.real());
}
/**
Complex multiplication by a double.
#param d is the double to multiply by.
#return z*d where z = a+i*b and d = double
*/
public Complex multiply(double d){
return new Complex(this.re * d,this.im * d);}
/**
Modulus of a Complex number or the distance from the origin in
* the polar coordinate plane.
#return |z| where z = a + i*b.
*/
public double mod() {
if ( re != 0.0 || im != 0.0)
return Math.sqrt(re*re + im*im);
else
return 0.0;
}
/**
* Modulus of a Complex number squared
* #param z = a + i*b
* #return |z|^2 where z = a + i*b
*/
public double abs(Complex z) {
return Math.sqrt(Math.pow(re*re, 2) + Math.pow(im*im, 2));
}
/**
Division of Complex numbers (doesn't change this Complex number).
<br>(a+i*b) / (c+i*d) = (a+i*b)*(c-i*d) / (c+i*d)*(c-i*d) =
* (a*c+b*d) + i*(b*c-a*d) / (c^2-d^2)
#param t is the number to divide by
#return new Complex number z/t where z = a+i*b
*/
public Complex divide (Complex t) {
double denom = Math.pow(t.mod(), 2); // Square the modulus
return new Complex((re * t.real() + im * t.imag()) / denom,
(im * t.real() - re * t.imag()) / denom);
}
/**
Division of Complex number by a double.
#param d is the double to divide
#return new Complex number z/d where z = a+i*b
*/
public Complex divide(double d){
return new Complex(this.re / d, this.im / d);
}
/**
Exponential of a complex number (z is unchanged).
<br> e^(a+i*b) = e^a * e^(i*b) = e^a * (cos(b) + i*sin(b))
#return exp(z) where z = a+i*b
*/
public Complex exp () {
return new Complex(Math.exp(re) * Math.cos(im), Math.exp(re) *
Math.sin(im));
}
/**
The Argument of a Complex number or the angle in radians
with respect to polar coordinates.
<br> Tan(theta) = b / a, theta = Arctan(b / a)
<br> a is the real part on the horizontal axis
<br> b is the imaginary part of the vertical axis
#return arg(z) where z = a+i*b.
*/
public double arg() {
return Math.atan2(im, re);
}
/**
The log or principal branch of a Complex number (z is unchanged).
<br> Log(a+i*b) = ln|a+i*b| + i*Arg(z) = ln(sqrt(a^2+b^2))
* + i*Arg(z) = ln (mod(z)) + i*Arctan(b/a)
#return log(z) where z = a+i*b
*/
public Complex log() {
return new Complex(Math.log(this.mod()), this.arg());
}
/**
The square root of a Complex number (z is unchanged).
Returns the principal branch of the square root.
<br> z = e^(i*theta) = r*cos(theta) + i*r*sin(theta)
<br> r = sqrt(a^2+b^2)
<br> cos(theta) = a / r, sin(theta) = b / r
<br> By De Moivre's Theorem, sqrt(z) = sqrt(a+i*b) =
* e^(i*theta / 2) = r(cos(theta/2) + i*sin(theta/2))
#return sqrt(z) where z = a+i*b
*/
public Complex sqrt() {
double r = this.mod();
double halfTheta = this.arg() / 2;
return new Complex(Math.sqrt(r) * Math.cos(halfTheta), Math.sqrt(r) *
Math.sin(halfTheta));
}
/**
The real cosh function for Complex numbers.
<br> cosh(theta) = (e^(theta) + e^(-theta)) / 2
#return cosh(theta)
*/
private double cosh(double theta) {
return (Math.exp(theta) + Math.exp(-theta)) / 2;
}
/**
The real sinh function for Complex numbers.
<br> sinh(theta) = (e^(theta) - e^(-theta)) / 2
#return sinh(theta)
*/
private double sinh(double theta) {
return (Math.exp(theta) - Math.exp(-theta)) / 2;
}
/**
The sin function for the Complex number (z is unchanged).
<br> sin(a+i*b) = cosh(b)*sin(a) + i*(sinh(b)*cos(a))
#return sin(z) where z = a+i*b
*/
public Complex sin() {
return new Complex(cosh(im) * Math.sin(re), sinh(im)*
Math.cos(re));
}
/**
The cos function for the Complex number (z is unchanged).
<br> cos(a +i*b) = cosh(b)*cos(a) + i*(-sinh(b)*sin(a))
#return cos(z) where z = a+i*b
*/
public Complex cos() {
return new Complex(cosh(im) * Math.cos(re), -sinh(im) *
Math.sin(re));
}
/**
The hyperbolic sin of the Complex number (z is unchanged).
<br> sinh(a+i*b) = sinh(a)*cos(b) + i*(cosh(a)*sin(b))
#return sinh(z) where z = a+i*b
*/
public Complex sinh() {
return new Complex(sinh(re) * Math.cos(im), cosh(re) *
Math.sin(im));
}
/**
The hyperbolic cosine of the Complex number (z is unchanged).
<br> cosh(a+i*b) = cosh(a)*cos(b) + i*(sinh(a)*sin(b))
#return cosh(z) where z = a+i*b
*/
public Complex cosh() {
return new Complex(cosh(re) *Math.cos(im), sinh(re) *
Math.sin(im));
}
/**
The tan of the Complex number (z is unchanged).
<br> tan (a+i*b) = sin(a+i*b) / cos(a+i*b)
#return tan(z) where z = a+i*b
*/
public Complex tan() {
return (this.sin()).divide(this.cos());
}
/**
The arctan of the Complex number (z is unchanged).
<br> tan^(-1)(a+i*b) = 1/2 i*(log(1-i*(a+b*i))-log(1+i*(a+b*i))) =
<br> -1/2 i*(log(i*a - b+1)-log(-i*a + b+1))
#return arctan(z) where z = a+i*b
*/
public Complex atan(){
Complex ima = new Complex(0.0,-1.0); //multiply by negative i
Complex num = new Complex(this.re,this.im-1.0);
Complex den = new Complex(-this.re,-this.im-1.0);
Complex two = new Complex(2.0, 0.0); // divide by 2
return ima.multiply(num.divide(den).log()).divide(two);}
/**
* The Math.pow equivalent of two Complex numbers.
* #param z - the complex base in the form z = a + i*b
* #return z^y where z = a + i*b and y = c + i*d
*/
public Complex pow(Complex z){
Complex a = z.multiply(this.log());
return a.exp();
}
/**
* The Math.pow equivalent of a Complex number to the power
* of a double.
* #param d - the double to be taken as the power.
* #return z^d where z = a + i*b and d = double
*/
public Complex pow(double d){
Complex a=(this.log()).multiply(d);
return a.exp();
}
/**
Override the .toString() method to generate complex numbers, the
* string representation is now a literal Complex number.
#return a+i*b, a-i*b, a, or i*b as desired.
*/
public String toString() {
if (re != 0.0 && im > 0.0) {
return re + " + " + im +"i";
}
if (re !=0.0 && im < 0.0) {
return re + " - "+ (-im) + "i";
}
if (im == 0.0) {
return String.valueOf(re);
}
if (re == 0.0) {
return im + "i";
}
return re + " + i*" + im;
}
public static void main(String[] args) {
Complex s = new Complex(2.0, 3.0);
Complex y = new Complex(3.0, 4.0);
Complex d = new Complex(4.0, 2.0);
Complex x = new Complex(1.0, 0.0);
System.out.println(s.atan());
System.out.println(s.divide(d));
System.out.println(s.im);
System.out.println(s.pow(y));
System.out.println(s.pow(2.0));
}
}
I did some preliminary testing and it seems that both the public static Complex f and public static Complex AbelPlana methods work fine. I checked these calculations against Mathematica. The method for
public static Complex adaptiveQuad(double a, double b, Complex z)
also works (for low values).
Calculation of the Riemann Zeta Function in the form Zeta(s) = a + ib.
Enter the value of [a] inside the Riemann Zeta Function: -12
Enter the value of [b] inside the Riemann Zeta Function: 1.2
The value for Zeta(s) is 0.0900630360334386 + 0.08241454022912213*i
Total time taken is 0.014 seconds.
Enter the value of [a] inside the Riemann Zeta Function: 0.3
Enter the value of [b] inside the Riemann Zeta Function: -2.1
The value for Zeta(s) is 0.4003421605328948 + 0.2570024810252463*i
Total time taken is 0.005 seconds.
Enter the value of [a] inside the Riemann Zeta Function: 1
Enter the value of [b] inside the Riemann Zeta Function: 2
The value for Zeta(s) is 0.598165521081844 - 0.35185471257583556*i
Total time taken is 0.005 seconds.
Enter the value of [a] inside the Riemann Zeta Function: 0.5
Enter the value of [b] inside the Riemann Zeta Function: 10
The value for Zeta(s) is 1.5448963436469043 - 0.1153378574814412*i
Total time taken is 0.014 seconds.
Something is clearly wrong with larger values.
Enter the value of [a] inside the Riemann Zeta Function: 24
Enter the value of [b] inside the Riemann Zeta Function: -8
The value for Zeta(s) is 164561.70457820524 + 302628.94685036544*i
Total time taken is 0.003 seconds.
I scanned the internet and couldn't find a method for numerical integration of complex functions. The integral for the approximation is shown in here. It doesn't seem like I can use this relationship in the program (it needs to calculate the Zeta(z) for z = a+i*b anyhow).
I searched and found this, and this. Do I need to reference the Apache Commons Math library to numerically integrate a complex function? I would prefer to write a method to do this myself. My current knowledge doesn't seem to be sufficient, all of the numerical integration methods that I know directly approximate real-valued functions.
I will review why my method fails for large values...
In a program, a double is being converted to BigDecimal. This returns a very strange error message.
public static double riemannFuncForm(double s) {
double term = Math.pow(2, s)*Math.pow(Math.PI, s-1)*
(Math.sin((Math.PI*s)/2))*gamma(1-s);
if(s == 1.0 || (s <= -1 && s % 2 == 0) )
return 0;
else if (s >= 0 && s < 2)
return getSimpsonSum(s);
else if (s > -1 && s < 0)
return term*getSimpsonSum(1-s);
else
return term*standardZeta(1-s);
}
BigDecimal val = BigDecimal.valueOf(riemannFuncForm(s));
System.out.println("Value for the Zeta Function = "
+ val.toEngineeringString());
This returns
Exception in thread "main" java.lang.NumberFormatException
What is causing this error message? Does BigDecimal.valueOf(double) not work correctly since this is referenced through another method?
Full program
/**************************************************************************
**
** Euler-Riemann Zeta Function
**
**************************************************************************
** XXXXXXXXXX
** 06/20/2015
**
** This program computes the value for Zeta(s) using the standard form
** of Zeta(s), the Riemann functional equation, and the Cauchy-Schlomilch
** transformation. A recursive method named riemannFuncForm has been created
** to handle computations of Zeta(s) for s < 2. Simpson's method is
** used to approximate the definite integral calculated by the
** Cauchy-Schlomilch transformation.
**************************************************************************/
import java.util.Scanner;
import java.math.*;
public class ZetaMain {
// Main method
public static void main(String[] args) {
ZetaMain();
}
// Asks the user to input a value for s.
public static void ZetaMain() {
double s = 0;
double start, stop, totalTime;
Scanner scan = new Scanner(System.in);
System.out.print("Enter the value of s inside the Riemann Zeta " +
"Function: ");
try {
s = scan.nextDouble();
}
catch (Exception e) {
System.out.println("You must enter a positive integer greater " +
"than 1.");
}
start = System.currentTimeMillis();
if (s == 1)
System.out.println("The zeta function is undefined for Re(s) " +
"= 1.");
else if (s < 2) {
BigDecimal val = BigDecimal.valueOf(riemannFuncForm(s));
System.out.println("Value for the Zeta Function = "
+ val.toEngineeringString());
}
else
System.out.println("Value for the Zeta Function = "
+ BigDecimal.valueOf(getStandardSum(s)).toString());
stop = System.currentTimeMillis();
totalTime = (double) (stop-start) / 1000.0;
System.out.println("Total time taken is " + totalTime + " seconds.");
}
// Standard form of the Zeta function.
public static double standardZeta(double s) {
int n = 1;
double currentSum = 0;
double relativeError = 1;
double error = 0.000001;
double remainder;
while (relativeError > error) {
currentSum = Math.pow(n, -s) + currentSum;
remainder = 1 / ((s-1)* Math.pow(n, (s-1)));
relativeError = remainder / currentSum;
n++;
}
System.out.println("The number of terms summed was " + n + ".");
return currentSum;
}
// Returns the value calculated by the Standard form of the Zeta function.
public static double getStandardSum(double s){
return standardZeta(s);
}
// Approximation of the Gamma function through the Lanczos Approximation.
public static double gamma(double s){
double[] p = {0.99999999999980993, 676.5203681218851,
-1259.1392167224028, 771.32342877765313,
-176.61502916214059, 12.507343278686905,
-0.13857109526572012, 9.9843695780195716e-6,
1.5056327351493116e-7};
int g = 7;
// Implements Euler's Reflection Formula.
if(s < 0.5) return Math.PI / (Math.sin(Math.PI * s)
*gamma(1-s));
s -= 1;
double a = p[0];
double t = s + g + 0.5;
for(int i = 1; i < p.length; i++){
a += p[i] / (s+i);
}
return Math.sqrt(2*Math.PI)*Math.pow(t, s+0.5)
*Math.exp(-t)*a;
}
/* Riemann's Functional Equation - Directly calculates the value of
Zeta(s) for s < 2.
1. The first if statement handles the case when s < 0 and s is a
multiple of 2k. These are trivial zeroes where Zeta(s) is 0.
2. The second if statement handles the values of 0 < s < 2. Simpson's
method is used to numerically compute an approximation of the
definite integral.
3. The third if statement handles the values of -1 < s < 0. Recursion
is used alongside an approximation through Simpson's method.
4. The last if statement handles the case for s <= -1 and is not a
trivial zero. Recursion is used directly against the standard form
of Zeta(s).
*/
public static double riemannFuncForm(double s) {
double term = Math.pow(2, s)*Math.pow(Math.PI, s-1)*
(Math.sin((Math.PI*s)/2))*gamma(1-s);
if(s == 1.0 || (s <= -1 && s % 2 == 0) )
return 0;
else if (s >= 0 && s < 2)
return getSimpsonSum(s);
else if (s > -1 && s < 0)
return term*getSimpsonSum(1-s);
else
return term*standardZeta(1-s);
}
// Returns the function referenced inside the right hand side of the
// Cauchy-Schlomilch transformation for Zeta(s).
public static double function(double x, double s) {
double sech = 1 / Math.cosh(x); // Hyperbolic cosecant
double squared = Math.pow(sech, 2);
return ((Math.pow(x, s)) * squared);
}
// Simpson's rule - Approximates the definite integral of f from a to b.
public static double SimpsonsRule(double a, double b, double s, int n) {
double simpson, dx, x, sum4x, sum2x;
dx = (b-a) / n;
sum4x = 0.0;
sum2x = 0.0;
// 4/3 terms
for (int i = 1; i < n; i += 2) {
x = a + i * dx;
sum4x += function(x,s);
}
// 2/3 terms
for (int i = 2; i < n-1; i += 2) {
x = a + i * dx;
sum2x += function(x,s);
}
// Compute the integral approximation.
simpson = function(a,s) + function(a,b);
simpson = (dx / 3)*(simpson + 4 * sum4x + 2 * sum2x);
return simpson;
}
// Handles the error for for f(x) = t^s * sech(t)^2. The integration is
// done from 0 to 100.
// Stop Simspson's Method when the relative error is less than 1 * 10^-6
public static double SimpsonError(double a, double b, double s, int n)
{
double futureVal;
double absError = 1.0;
double finalValueOfN;
double numberOfIterations = 0.0;
double currentVal = SimpsonsRule(a,b,s,n);
while (absError / currentVal > 0.000001) {
n = 2*n;
futureVal = SimpsonsRule(a,b,s,n);
absError = Math.abs(futureVal - currentVal) / 15;
currentVal = futureVal;
}
// Find the number of iterations. N starts at 8 and doubles
// every iteration.
finalValueOfN = n / 8;
while (finalValueOfN % 2 == 0) {
finalValueOfN = finalValueOfN / 2;
numberOfIterations++;
}
System.out.println("The number of iterations is "
+ numberOfIterations + ".");
return currentVal;
}
// Returns an approximate sum of Zeta(s) through Simpson's rule.
public static double getSimpsonSum(double s) {
double constant = Math.pow(2, (2*s)-1) / (((Math.pow(2, s)) -2)*
(gamma(1+s)));
System.out.println("Did Simpson's Method.");
return constant*SimpsonError(0, 100, s, 8);
}
}
Would I have to change all of my double calculations to BigDecimal calculations in order to fix this?
Nope. All you would need to do is to catch and handle the NumberFormatException appropriately. Or, test for NaN and Inf before attempting to convert the double.
In this case, you are only using BigDecimal for formatting in "engineering" syntax. So another alternative would be to do the formatting directly. (Though I haven't found a simple way to do that yet.)
This error occurs with you because BigDecimal.valueOf(value) does not accept "NaN" "Not a Number" as parameter and the following expression will return NaN
Math.pow(2, s)*Math.pow(Math.PI, s-1)*(Math.sin((Math.PI*s)/2))*gamma(1-s)
this Math.pow(2, s)*Math.pow(Math.PI, s-1)*(Math.sin((Math.PI*s)/2)) will evaluate -0.0
and this function gamma(1-s) will evaluate "Infinity"
So -0.0 * Infinity equal NaN in java
please see this to know When can Java produce a NaN.
When can Java produce a NaN?