Java Newton Iteration - java

I'm trying to make a square root calculator with my own function which is sqrt and borrowing a already made one to test accuracy. The issue is every time I output my guess to the screen after putting it into the function the numbers just return as the same number inputted but it has a .0 on it. An example is, when I put in the number 2 I get back 2.0 which is wrong. Please help :)
import java.io.IOException;
import java.util.Scanner;
public class test {
/**
* Main method.
*
* #param args
* the command line arguments
* #throws IOException
*/
public static void main(String[] args) throws IOException {
Scanner data = new Scanner(System.in);
double root;
/*
* Put your main program code here; it may call myMethod as shown
*/
System.out.println("Please enter a root to be calculated:");
root = data.nextDouble();
double actual = root;
sqrt(root);
sqrt_(actual);
System.out.println(root);
System.out.println(actual);
/*
* Close input and output streams
*/
}
/**
* Computes estimate of square root of x to within relative error 0.01%.
*
* #param x
* positive number to compute square root of
* #return estimate of square root
*/
private static double sqrt(double x) {
double epilson = 0.0001;
double approx = 1;
int count = 0;
while ((Math.abs(approx - (x / approx)) > (0.0001 * approx))
&& (count < 100)) {
approx = 0.5 * (approx + (x / approx));
count++;
}
return approx;
}
public static double sqrt_(double c) {
if (c < 0) {
return Double.NaN;
}
double EPS = 1E-15;
double t = c;
while (Math.abs(t - c / t) > EPS * t) {
t = (c / t + t) / 2.0;
}
return t;
}
}

You are simply forgetting to assign your return values.
root = sqrt(root);
actual = sqrt_(actual);

Related

Pyramid of pin using Recursion

I want to print a pyramid of pins using recursion(no Loops). I got the code almost done, but my pyramid is upside down, and it is not formatted. How can I fix it.
Below is my source code:
public void pinPattern(int count) {
if(count == 1)
System.out.println("*");
else {
System.out.print("*");
pinPattern(count - 1);
}
}
public int numberOfPins(int n) {
if(n == 0)
return 0;
else {
pinPattern(n);
return n + numberOfPins(n - 1);
}
}
public static void main(String[] args) {
Recursion x = new Recursion();
System.out.println("The number of pin: " + x.numberOfPins(5));
}
Thanks in advance.
So there are two considerations here. First, the need to have the pyramid go the other direction. If it is printing upside-down, then instead of counting down (which goes from max to min), invert the approach. Something like:
public static int pinPatternUp(int numPins, int maxPins)
{
if (numPins <= maxPins) {
// this will add spaces
spaces(maxPins - numPins);
pins(numPins);
return numPins + (pinPattern(numPins + 1, maxPins));
}
return 0;
}
The logic for the pins method (which in the OP's code was 'pinPattern) in the OP's approach is essentially fine for either direction. However, making this change (so that there is a space after each*`) will allow for a bit better formatting.
System.out.print("* ");
The second question is one of formatting. In this case, we can look at the pyramid as requiring N spaces before the first output. And with a bit of investigation, it appears that a given line will have the total number of rows - the current row in terms of spaces. Using recursion, it is possible to do something like:
public static void spaces(int num)
{
if (num == 0) {
return;
}
System.out.print(" ");
spaces(num - 1);
}
Note that one can now have an "up" or "down" facing pyramid depending upon whether the pinPattern is increasing or decreasing.
Note: due to some editing, the method names do not exactly align with the OP's.
public static void main(String[] args)
{
pinPatternUp(1, 5);
pinPatternDown(5, 5);
}
Output if run up and then down:
*
* *
* * *
* * * *
* * * * *
* * * * *
* * * *
* * *
* *
*

Converting double to BigDecimal in Java

I wrote a Java program that calculates values for the Riemann Zeta Function. Inside the program, I made a library to calculate necessary complex functions such as atan, cos, etc. Everything inside both programs is accessed through the double and BigDecimal data types. This creates major issues when evaluating large values for the Zeta function.
The numerical approximation for the Zeta function references
Directly evaluating this approximation at high values creates issues when s has a large complex form, such as s = (230+30i). I am very grateful to get information about this here. The evaluation of S2.minus(S1) creates errors because I wrote something wrong in the adaptiveQuad method.
As an example, Zeta(2+3i) through this program generates
Calculation of the Riemann Zeta Function in the form Zeta(s) = a + ib.
Enter the value of [a] inside the Riemann Zeta Function: 2
Enter the value of [b] inside the Riemann Zeta Function: 3
The value for Zeta(s) is 7.980219851133409E-1 - 1.137443081631288E-1*i
Total time taken is 0.469 seconds.
Which is correct.
Zeta(100+0i) generates
Calculation of the Riemann Zeta Function in the form Zeta(s) = a + ib.
Enter the value of [a] inside the Riemann Zeta Function: 100
Enter the value of [b] inside the Riemann Zeta Function: 0
The value for Zeta(s) is 1.000000000153236E0
Total time taken is 0.672 seconds.
Which is also correct as compared to Wolfram. The problem is due to something inside the method labelled adaptiveQuad.
Zeta(230+30i) generates
Calculation of the Riemann Zeta Function in the form Zeta(s) = a + ib.
Enter the value of [a] inside the Riemann Zeta Function: 230
Enter the value of [b] inside the Riemann Zeta Function: 30
The value for Zeta(s) is 0.999999999999093108519845391615339162047254997503854254342793916541606842461539820124897870147977114468145672577664412128509813042591501204781683860384769321084473925620572315416715721728082468412672467499199310913504362891199180150973087384370909918493750428733837552915328069343498987460727711606978118652477860450744628906250 - 38.005428584222228490409289204403133867487950535704812764806874887805043029499897666636162309572126423385487374863788363786029170239477119910868455777891701471328505006916099918492113970510619110472506796418206225648616641319533972054228283869713393805956289770456519729094756021581247296126093715429306030273437500E-15*i
Total time taken is 1.746 seconds.
The imaginary part is a bit off as compared to Wolfram.
The algorithm to evaluate the integral is known as Adaptive Quadrature and a double Java implementation is found here. The adaptive quad method applies the following
// adaptive quadrature
public static double adaptive(double a, double b) {
double h = b - a;
double c = (a + b) / 2.0;
double d = (a + c) / 2.0;
double e = (b + c) / 2.0;
double Q1 = h/6 * (f(a) + 4*f(c) + f(b));
double Q2 = h/12 * (f(a) + 4*f(d) + 2*f(c) + 4*f(e) + f(b));
if (Math.abs(Q2 - Q1) <= EPSILON)
return Q2 + (Q2 - Q1) / 15;
else
return adaptive(a, c) + adaptive(c, b);
}
Here is my fourth attempt at writing the program
/**************************************************************************
**
** Abel-Plana Formula for the Zeta Function
**
**************************************************************************
** Axion004
** 08/16/2015
**
** This program computes the value for Zeta(z) 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 AbelMain5 extends Complex {
private static MathContext MC = new MathContext(512,
RoundingMode.HALF_EVEN);
public static void main(String[] args) {
AbelMain();
}
// Main method
public static void AbelMain() {
double re = 0, 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(new BigDecimal(re), new BigDecimal(im));
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(z) in the Abel-Plana formula.
* <br> Numerator = Sin(z * arctan(t))
* <br> Denominator = (1 + t^2)^(z/2) * (e^(2*pi*t) - 1)
* #param t - the value of t passed into the integrand.
* #param z - The complex value of z = a + i*b
* #return the value of the complex function.
*/
public static Complex f(double t, Complex z) {
Complex num = (z.multiply(Math.atan(t))).sin();
Complex D1 = new Complex(1 + t*t).pow(z.divide(TWO));
Complex D2 = new Complex(Math.pow(Math.E, 2.0*Math.PI*t) - 1.0);
Complex den = D1.multiply(D2);
return num.divide(den, MC);
}
/**
* Adaptive quadrature - See http://www.mathworks.com/moler/quad.pdf
* #param a - the lower bound of integration.
* #param b - the upper bound of integration.
* #param z - The complex value of z = a + i*b
* #return the approximate numerical value of the integral.
*/
public static Complex adaptiveQuad(double a, double b, Complex z) {
double EPSILON = 1E-10;
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, z).add(f(c, z).multiply(FOUR)).add(f(b, z))).
multiply(step / 6.0);
Complex S2 = (f(a, z).add(f(d, z).multiply(FOUR)).add(f(c, z).multiply
(TWO)).add(f(e, z).multiply(FOUR)).add(f(b, z))).multiply
(step / 12.0);
Complex result = (S2.subtract(S1)).divide(FIFTEEN, MC);
if(S2.subtract(S1).mod() <= EPSILON)
return S2.add(result);
else
return adaptiveQuad(a, c, z).add(adaptiveQuad(c, b, z));
}
/**
* The definite integral for Zeta(z) in the Abel-Plana formula.
* <br> value = 1/2 + 1/(z-1) + 2 * Integral
* #param z - The complex value of z = a + i*b
* #return the value of Zeta(z) through value and the
* quadrature approximation.
*/
public static Complex AbelPlana(Complex z) {
Complex C1 = ONEHALF.add(ONE.divide(z.subtract(ONE), MC));
Complex C2 = TWO.multiply(adaptiveQuad(1E-16, 100.0, z));
if ( z.real().doubleValue() == 0 && z.imag().doubleValue() == 0)
return new Complex(0.0, 0.0);
else
return C1.add(C2);
}
}
Complex numbers (BigDecimal)
/**************************************************************************
**
** Complex Numbers
**
**************************************************************************
** Axion004
** 08/20/2015
**
** This class is necessary as a helper class for the calculation of
** imaginary numbers. The calculation of Zeta(z) inside AbelMain is in
** the form of z = a + i*b.
**************************************************************************/
import java.math.BigDecimal;
import java.math.MathContext;
import java.text.DecimalFormat;
import java.text.NumberFormat;
public class Complex extends Object{
private BigDecimal re;
private BigDecimal im;
/**
BigDecimal constant for zero
*/
final static Complex ZERO = new Complex(BigDecimal.ZERO) ;
/**
BigDecimal constant for one half
*/
final static Complex ONEHALF = new Complex(new BigDecimal(0.5));
/**
BigDecimal constant for one
*/
final static Complex ONE = new Complex(BigDecimal.ONE);
/**
BigDecimal constant for two
*/
final static Complex TWO = new Complex(new BigDecimal(2.0));
/**
BigDecimal constant for four
*/
final static Complex FOUR = new Complex(new BigDecimal(4.0)) ;
/**
BigDecimal constant for fifteen
*/
final static Complex FIFTEEN = new Complex(new BigDecimal(15.0)) ;
/**
Default constructor equivalent to zero
*/
public Complex() {
re = BigDecimal.ZERO;
im = BigDecimal.ZERO;
}
/**
Constructor with real part only
#param x Real part, BigDecimal
*/
public Complex(BigDecimal x) {
re = x;
im = BigDecimal.ZERO;
}
/**
Constructor with real part only
#param x Real part, double
*/
public Complex(double x) {
re = new BigDecimal(x);
im = BigDecimal.ZERO;
}
/**
Constructor with real and imaginary parts in double format.
#param x Real part
#param y Imaginary part
*/
public Complex(double x, double y) {
re= new BigDecimal(x);
im= new BigDecimal(y);
}
/**
Constructor for the complex number z = a + i*b
#param re Real part
#param im Imaginary part
*/
public Complex (BigDecimal re, BigDecimal im) {
this.re = re;
this.im = im;
}
/**
Real part of the Complex number
#return Re[z] where z = a + i*b.
*/
public BigDecimal real() {
return re;
}
/**
Imaginary part of the Complex number
#return Im[z] where z = a + i*b.
*/
public BigDecimal 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.negate());
}
/**
* Returns the sum of this and the parameter.
#param augend the number to add
#param mc the context to use
#return this + augend
*/
public Complex add(Complex augend,MathContext mc)
{
//(a+bi)+(c+di) = (a + c) + (b + d)i
return new Complex(
re.add(augend.re,mc),
im.add(augend.im,mc));
}
/**
Equivalent to add(augend, MathContext.UNLIMITED)
#param augend the number to add
#return this + augend
*/
public Complex add(Complex augend)
{
return add(augend, MathContext.UNLIMITED);
}
/**
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){
BigDecimal augend = new BigDecimal(d);
return new Complex(this.re.add(augend, MathContext.UNLIMITED),
this.im);
}
/**
* Returns the difference of this and the parameter.
#param subtrahend the number to subtract
#param mc the context to use
#return this - subtrahend
*/
public Complex subtract(Complex subtrahend, MathContext mc)
{
//(a+bi)-(c+di) = (a - c) + (b - d)i
return new Complex(
re.subtract(subtrahend.re,mc),
im.subtract(subtrahend.im,mc));
}
/**
* Equivalent to subtract(subtrahend, MathContext.UNLIMITED)
#param subtrahend the number to subtract
#return this - subtrahend
*/
public Complex subtract(Complex subtrahend)
{
return subtract(subtrahend,MathContext.UNLIMITED);
}
/**
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 subtract(double d){
BigDecimal subtrahend = new BigDecimal(d);
return new Complex(this.re.subtract(subtrahend, MathContext.UNLIMITED),
this.im);
}
/**
* Returns the product of this and the parameter.
#param multiplicand the number to multiply by
#param mc the context to use
#return this * multiplicand
*/
public Complex multiply(Complex multiplicand, MathContext mc)
{
//(a+bi)(c+di) = (ac - bd) + (ad + bc)i
return new Complex(
re.multiply(multiplicand.re,mc).subtract(im.multiply
(multiplicand.im,mc),mc),
re.multiply(multiplicand.im,mc).add(im.multiply
(multiplicand.re,mc),mc));
}
/**
Equivalent to multiply(multiplicand, MathContext.UNLIMITED)
#param multiplicand the number to multiply by
#return this * multiplicand
*/
public Complex multiply(Complex multiplicand)
{
return multiply(multiplicand,MathContext.UNLIMITED);
}
/**
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){
BigDecimal multiplicand = new BigDecimal(d);
return new Complex(this.re.multiply(multiplicand, MathContext.UNLIMITED)
,this.im.multiply(multiplicand, MathContext.UNLIMITED));
}
/**
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.doubleValue() != 0.0 || im.doubleValue() != 0.0)
return Math.sqrt(re.multiply(re).add(im.multiply(im))
.doubleValue());
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) {
double doubleRe = re.doubleValue();
double doubleIm = im.doubleValue();
return doubleRe * doubleRe + doubleIm * doubleIm;
}
public Complex divide(Complex divisor)
{
return divide(divisor,MathContext.UNLIMITED);
}
/**
* The absolute value squared.
* #return The sum of the squares of real and imaginary parts.
* This is the square of Complex.abs() .
*/
public BigDecimal norm()
{
return re.multiply(re).add(im.multiply(im)) ;
}
/**
* The absolute value of a BigDecimal.
* #param mc amount of precision
* #return BigDecimal.abs()
*/
public BigDecimal abs(MathContext mc)
{
return BigDecimalMath.sqrt(norm(),mc) ;
}
/** The inverse of the the Complex number.
#param mc amount of precision
#return 1/this
*/
public Complex inverse(MathContext mc)
{
final BigDecimal hyp = norm() ;
/* 1/(x+iy)= (x-iy)/(x^2+y^2 */
return new Complex( re.divide(hyp,mc), im.divide(hyp,mc)
.negate() ) ;
}
/** Divide through another BigComplex number.
#param oth the other complex number
#param mc amount of precision
#return this/other
*/
public Complex divide(Complex oth, MathContext mc)
{
/* implementation: (x+iy)/(a+ib)= (x+iy)* 1/(a+ib) */
return multiply(oth.inverse(mc),mc) ;
}
/**
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){
BigDecimal divisor = new BigDecimal(d);
return new Complex(this.re.divide(divisor, MathContext.UNLIMITED),
this.im.divide(divisor, MathContext.UNLIMITED));
}
/**
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.doubleValue()) * Math.cos(im.
doubleValue()), Math.exp(re.doubleValue()) *
Math.sin(im.doubleValue()));
}
/**
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.doubleValue(), re.doubleValue());
}
/**
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.doubleValue()) * Math.sin(re.doubleValue()),
sinh(im.doubleValue())* Math.cos(re.doubleValue()));
}
/**
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.doubleValue()) * Math.cos(re.doubleValue()),
-sinh(im.doubleValue()) * Math.sin(re.doubleValue()));
}
/**
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.doubleValue()) * Math.cos(im.doubleValue()),
cosh(re.doubleValue()) * Math.sin(im.doubleValue()));
}
/**
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.doubleValue()) *Math.cos(im.doubleValue()),
sinh(re.doubleValue()) * Math.sin(im.doubleValue()));
}
/**
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.doubleValue(),this.im.doubleValue()
-1.0);
Complex den = new Complex(this.re.negate().doubleValue(),this.im
.negate().doubleValue()-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(), MathContext.UNLIMITED);
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() {
NumberFormat formatter = new DecimalFormat();
formatter = new DecimalFormat("#.###############E0");
if (re.doubleValue() != 0.0 && im.doubleValue() > 0.0) {
return formatter.format(re) + " + " + formatter.format(im)
+"*i";
}
if (re.doubleValue() !=0.0 && im.doubleValue() < 0.0) {
return formatter.format(re) + " - "+ formatter.format(im.negate())
+ "*i";
}
if (im.doubleValue() == 0.0) {
return formatter.format(re);
}
if (re.doubleValue() == 0.0) {
return formatter.format(im) + "*i";
}
return formatter.format(re) + " + i*" + formatter.format(im);
}
}
I am reviewing the answer below.
One problem may be due to
Complex num = (z.multiply(Math.atan(t))).sin();
Complex D1 = new Complex(1 + t*t).pow(z.divide(TWO));
Complex D2 = new Complex(Math.pow(Math.E, 2.0*Math.PI*t) - 1.0);
Complex den = D1.multiply(D2, MathContext.UNLIMITED);
I am not applying BigDecimal.pow(BigDecimal). Although, I don't think this is the direct issue which causes the floating point arithmetic to create differences.
Edit: I tried a new integral approximation of the Zeta function. Ultimately, I will develop a new method to calculate BigDecimal.pow(BigDecimal).
Caveat I agree with all the comments in #laune's answer, but I get the impression you may wish to pursue this anyway. Make sure especially that you really do understand 1) and what that means for you - it's very easy to do a lot of heavy calculations to produce meaningless results.
Arbitrary precision floating point functions in Java
To reiterate a little, I think your problem really is with the maths and numerical method you have chosen, but here's an implementation using the Apfloat library. I'd strongly urge you to use the ready made arbitrary precision library (or a similar one) as it avoids any need for you to "roll your own" arbitrary precision maths functions (such as pow, exp,sin, atan etc). You say
Ultimately, I will develop a new method to calculate BigDecimal.pow(BigDecimal)
It's really hard to get that right.
You need to watch the precision of your constants, too - note I use an Apfloat sample implementation to calculate PI to a large number (for some definition of large!) of sig figs. I am to some degree trusting that the Apfloat library uses suitably precise values for e in exponentiation - the source is available if you want to check.
Different integral formulations to calculate zeta
You put up three different integration based methods in one of your edits:
The one labelled 25.5.12 is the one that you currently have in the question and (although that can be calculated at zero easily), it is hard to work with due to 2) in #laune's answer. I implemented 25.5.12 as integrand1() in the code - I urge you to plot it with range of t for different s = a + 0i and understand how it behaves. Or look at the plots in the zeta article on Wolfram's mathworld. The one labelled 25.5.11 I implemented via integrand2() and the code in the configuration I publish below.
Code
While I'm a bit reluctant to post code that will no doubt find wrong results in some configurations due to all the things above - I have encoded what you are trying to do below, using arbitrary precision floating point objects for the variables.
If you want to change which formulation you use (e.g. from 25.5.11 to 25.5.12), you can change which integrand the wrapper function f() returns or, better yet, change adaptiveQuad to take in an arbitrary integrand method wrapped in a class with an interface... You will also have to alter the arithmetic in findZeta() if you want to use one of the other integral formulations.
Play with the constants at the start to your heart's content. I haven't tested lots of combinations, as I think the maths problems here override the programming ones.
I've left it set up to do 2+3i in about 2000 calls to the adaptive quadature method and match the first 15 or so digits of the Wolfram value.
I've tested it still works with PRECISION = 120l and EPSILON=1e-15. The program matches Wolfram alpha in the first 18 or so significant figures for the three test cases you provide. The last one (230+30i) takes a long time even on a fast computer - it calls the integrand fucntion some 100,000+ times. Note that I use 40 for the value of INFINITY in the integral - not very high - but higher values exhibit the problem 1) as already discussed...
N.B. This is not fast (you'll be measuring in minutes or hours, not seconds - but you only get really quick if you want to accept that 10^-15 ~= 10^-70 as most people would!!). It will give you some digits that match Wolfram Alpha ;) You might want to take PRECISION down to about 20, INFINITY to 10 and EPSILON to 1e-10 to verify a few results with small s first... I've left in some printing so it tells you every 100th time adaptiveQuad is called for comfort.
Reiteration However good your precision - it's not going to overcome the mathematical characteristics of the functions involved in this way of calculating zeta. I strongly doubt this is how Wolfram alpha does it, for instance. Look up series summation methods if you want more tractable methods.
import java.io.PrintWriter;
import org.apfloat.ApcomplexMath;
import org.apfloat.Apcomplex;
import org.apfloat.Apfloat;
import org.apfloat.samples.Pi;
public class ZetaFinder
{
//Number of sig figs accuracy. Note that infinite should be reserved
private static long PRECISION = 40l;
// Convergence criterion for integration
static Apfloat EPSILON = new Apfloat("1e-15",PRECISION);
//Value of PI - enhanced using Apfloat library sample calculation of Pi in constructor,
//Fast enough that we don't need to hard code the value in.
//You could code hard value in for perf enhancement
static Apfloat PI = null; //new Apfloat("3.14159");
//Integration limits - I found too high a value for "infinity" causes integration
//to terminate on first iteration. Plot the integrand to see why...
static Apfloat INFINITE_LIMIT = new Apfloat("40",PRECISION);
static Apfloat ZERO_LIMIT = new Apfloat("1e-16",PRECISION); //You can use zero for the 25.5.12
static Apfloat one = new Apfloat("1",PRECISION);
static Apfloat two = new Apfloat("2",PRECISION);
static Apfloat four = new Apfloat("4",PRECISION);
static Apfloat six = new Apfloat("6",PRECISION);
static Apfloat twelve = new Apfloat("12",PRECISION);
static Apfloat fifteen = new Apfloat("15",PRECISION);
static int counter = 0;
Apcomplex s = null;
public ZetaFinder(Apcomplex s)
{
this.s = s;
Pi.setOut(new PrintWriter(System.out, true));
Pi.setErr(new PrintWriter(System.err, true));
PI = (new Pi.RamanujanPiCalculator(PRECISION+10, 10)).execute(); //Get Pi to a higher precision than integer consts
System.out.println("Created a Zeta Finder based on Abel-Plana for s="+s.toString() + " using PI="+PI.toString());
}
public static void main(String[] args)
{
Apfloat re = new Apfloat("2", PRECISION);
Apfloat im = new Apfloat("3", PRECISION);
Apcomplex s = new Apcomplex(re,im);
ZetaFinder finder = new ZetaFinder(s);
System.out.println(finder.findZeta());
}
private Apcomplex findZeta()
{
Apcomplex retval = null;
//Method currently in question (a.k.a. 25.5.12)
//Apcomplex mult = ApcomplexMath.pow(two, this.s);
//Apcomplex firstterm = (ApcomplexMath.pow(two, (this.s.add(one.negate())))).divide(this.s.add(one.negate()));
//Easier integrand method (a.k.a. 25.5.11)
Apcomplex mult = two;
Apcomplex firstterm = (one.divide(two)).add(one.divide(this.s.add(one.negate())));
Apfloat limita = ZERO_LIMIT;//Apfloat.ZERO;
Apfloat limitb = INFINITE_LIMIT;
System.out.println("Trying to integrate between " + limita.toString() + " and " + limitb.toString());
Apcomplex integral = adaptiveQuad(limita, limitb);
retval = firstterm.add((mult.multiply(integral)));
return retval;
}
private Apcomplex adaptiveQuad(Apfloat a, Apfloat b) {
//if (counter % 100 == 0)
{
System.out.println("In here for the " + counter + "th time");
}
counter++;
Apfloat h = b.add(a.negate());
Apfloat c = (a.add(b)).divide(two);
Apfloat d = (a.add(c)).divide(two);
Apfloat e = (b.add(c)).divide(two);
Apcomplex Q1 = (h.divide(six)).multiply(f(a).add(four.multiply(f(c))).add(f(b)));
Apcomplex Q2 = (h.divide(twelve)).multiply(f(a).add(four.multiply(f(d))).add(two.multiply(f(c))).add(four.multiply(f(e))).add(f(b)));
if (ApcomplexMath.abs(Q2.add(Q1.negate())).compareTo(EPSILON) < 0)
{
System.out.println("Returning");
return Q2.add((Q2.add(Q1.negate())).divide(fifteen));
}
else
{
System.out.println("Recursing with intervals "+a+" to " + c + " and " + c + " to " +d);
return adaptiveQuad(a, c).add(adaptiveQuad(c, b));
}
}
private Apcomplex f(Apfloat x)
{
return integrand2(x);
}
/*
* Simple test integrand (z^2)
*
* Can test implementation by asserting that the adaptiveQuad
* with this function evaluates to z^3 / 3
*/
private Apcomplex integrandTest(Apfloat t)
{
return ApcomplexMath.pow(t, two);
}
/*
* Abel-Plana formulation integrand
*/
private Apcomplex integrand1(Apfloat t)
{
Apcomplex numerator = ApcomplexMath.sin(this.s.multiply(ApcomplexMath.atan(t)));
Apcomplex bottomlinefirstbr = one.add(ApcomplexMath.pow(t, two));
Apcomplex D1 = ApcomplexMath.pow(bottomlinefirstbr, this.s.divide(two));
Apcomplex D2 = (ApcomplexMath.exp(PI.multiply(t))).add(one);
Apcomplex denominator = D1.multiply(D2);
Apcomplex retval = numerator.divide(denominator);
//System.out.println("Integrand evaluated at "+t+ " is "+retval);
return retval;
}
/*
* Abel-Plana formulation integrand 25.5.11
*/
private Apcomplex integrand2(Apfloat t)
{
Apcomplex numerator = ApcomplexMath.sin(this.s.multiply(ApcomplexMath.atan(t)));
Apcomplex bottomlinefirstbr = one.add(ApcomplexMath.pow(t, two));
Apcomplex D1 = ApcomplexMath.pow(bottomlinefirstbr, this.s.divide(two));
Apcomplex D2 = ApcomplexMath.exp(two.multiply(PI.multiply(t))).add(one.negate());
Apcomplex denominator = D1.multiply(D2);
Apcomplex retval = numerator.divide(denominator);
//System.out.println("Integrand evaluated at "+t+ " is "+retval);
return retval;
}
}
A note on "correctness"
Note that in your answer - you are calling zeta(2+3i) and zeta(100) "correct" as compared to Wolfram when they exhibit errors of ~1e-10 and ~1e-9 respectively (they differ in the 10th and 9th decimal place), but you are worried about zeta(230+30i) because it exhibits an error of order 10e-14 in the imaginary component (38e-15 vs 5e-70 which are both very near zero). So in some senses the one you are calling "wrong" is closer to the Wolfram value than the ones you call "correct". Maybe you are worried that the leading digits are different, but this isn't really a measure of accuracy there.
A final note
Unless you're doing it to learn about how functions behave and how floating point precision interacts with it - Don't do things this way. Even Apfloat's own documentation says:
This package is designed for extreme precision. The result might have
a few digits less than you'd expect (about 10) and the last few (about
10) digits in ther result might be inaccurate. If you plan to use
numbers with only a few hundred digits, use a program like PARI (it's
free and available from ftp://megrez.math.u-bordeaux.fr) or a
commercial program like Mathematica or Maple if possible.
I'd add mpmath in python to this list as a free alternative now.
(1) The integration uses adaptQuad, starting with an interval [0,10]. For z=a+ib with increasingly larger values of a and b=0, the integrand is an increasingly oscillating function, with the number of zeros in [0,5] alone being proportional to a and raising to 43 for z=100.
Therefore, starting the approximation with an interval that includes one or more zeros is risky, as the program as posted shows quite clearly. For z=100, the integrand is 0, -2.08E-78 and 7.12E-115 at 0, 5 and 10, respectively. Therefore, comparing the result of Simpson's formula to 1E-20 returns true, and the result is absolutely wrong.
(2) The computation in method AbelPlana involves two complex numbers, C1 and C2. For z=a+0i, they are real, and the table below shows their values for various values of a:
a C1 C2
10 5.689E1 1.024E3
20 2.759E4 1.048E6
30 1.851E7 1.073E9
40 1.409E10 1.099E12
60 9.770E15 1.152E18
100 6.402E27 1.267E30
Now we know that the values of ζ(a+0i) decrease towards 1 for increasing a. It is clearly impossible for two values above 1E15 to produce a meaningful result near one when subtracted from each other.
The table also suggests that for a good result of ζ(a+0i) by using this algorithm, C1 and C2*I (I is the integral) need to be computed with an accuracy of about 45 significant digits. (Arbitrary precision math does not avoid the pitfall described in (1).)
(3) Note that when using a library with arbitrary precision, values such a E and PI should be provided with a better precision than the double values in java.lang.Math can offer.
Edit
(25.5.11) has as many zeros in [0,10] as (25.5.12). The computation at 0 is tricky, but it's not a singularity. It does avoid issue (2).
For an answer regarding using arbitrary precision arithmetic with the integral method described in the OP - see my other answer
However, I got intrigued by this and thought that a series sum method should be more numerically stable. I found the Dirichlet series representation on Wikipedia and implemented it (fully runnable code below).
This gave me an interesting insight. If I set the convergence EPSILON to 1e-30 I get exactly the same digits and exponent (i.e. 1e-70 in the imaginary part) as Wolfram for zeta(100) and zeta(230+ 30i) and the algorithm terminates after only 1 or 2 terms adding to the sum. This suggests two things to me:
Wolfram alpha uses this sum method or something similar to calculate the values it returns.
The "correct"-ness of these values are hard to assess. For instance - zeta(100) has an exact value in terms of PI, so can be judged. I don't know whether this estimate of zeta(230+30i) is better or worse than the one found by the integral method
This method is really quite slow to converge to zeta(2+3i) and may need EPSILON taking lower to be usable.
I also found an academic paper that is a compendium of numeric methods to calculate zeta. This indicates to me that the underlying problem here is certainly "non-trivial"!!
Anyway - I leave the series sum implementation here as an alternative for anyone who may run across it in future.
import java.io.PrintWriter;
import org.apfloat.ApcomplexMath;
import org.apfloat.Apcomplex;
import org.apfloat.Apfloat;
import org.apfloat.ApfloatMath;
import org.apfloat.samples.Pi;
public class ZetaSeries {
//Number of sig figs accuracy. Note that infinite should be reserved
private static long PRECISION = 100l;
// Convergence criterion for integration
static Apfloat EPSILON = new Apfloat("1e-30",PRECISION);
static Apfloat one = new Apfloat("1",PRECISION);
static Apfloat two = new Apfloat("2",PRECISION);
static Apfloat minus_one = one.negate();
static Apfloat three = new Apfloat("3",PRECISION);
private Apcomplex s = null;
private Apcomplex s_plus_two = null;
public ZetaSeries(Apcomplex s) {
this.s = s;
this.s_plus_two = two.add(s);
}
public static void main(String[] args) {
Apfloat re = new Apfloat("230", PRECISION);
Apfloat im = new Apfloat("30", PRECISION);
Apcomplex s = new Apcomplex(re,im);
ZetaSeries z = new ZetaSeries(s);
System.out.println(z.findZeta());
}
private Apcomplex findZeta() {
Apcomplex series_sum = Apcomplex.ZERO;
Apcomplex multiplier = (one.divide(this.s.add(minus_one)));
int stop_condition = 1;
long n = 1;
while (stop_condition > 0)
{
Apcomplex term_to_add = sum_term(n);
stop_condition = ApcomplexMath.abs(term_to_add).compareTo(EPSILON);
series_sum = series_sum.add(term_to_add);
//if(n%50 == 0)
{
System.out.println("At iteration " + n + " : " + multiplier.multiply(series_sum));
}
n+=1;
}
return multiplier.multiply(series_sum);
}
private Apcomplex sum_term(long n_long) {
Apfloat n = new Apfloat(n_long, PRECISION);
Apfloat n_plus_one = n.add(one);
Apfloat two_n = two.multiply(n);
Apfloat t1 = (n.multiply(n_plus_one)).divide(two);
Apcomplex t2 = (two_n.add(three).add(this.s)).divide(ApcomplexMath.pow(n_plus_one,s_plus_two));
Apcomplex t3 = (two_n.add(minus_one).add(this.s.negate())).divide(ApcomplexMath.pow(n,this.s_plus_two));
return t1.multiply(t2.add(t3.negate()));
}
}

Java - Print Contents of an Object

I am trying to print the contents of a of my object Fraction(), but it keeps giving me a lot of errors and referring me back to where my print statements start. I have a toString() method that I created, but that does not seem to work either. Here is my class and tester class:
package fraction;
public class Fraction
{
/**
* The numerator and denominator.
*/
private int top;
private int bottom;
/**
* Creates the fraction 0/1
*/
public Fraction()
{
top = 0;
bottom = 1;
}
/**
* Creates the fraction n/1
* #param n an integer
*/
public Fraction(int n)
{
top = n;
bottom = 1;
}
/**
* Creates a fraction with the specified numerator and denominator
* #param n the numerator
* #param d the denominator
*/
public Fraction(int n, int d)
{
top = n;
bottom = d;
if (bottom == 0) {
throw new IllegalArgumentException();
}
}
/**
* Computes the sum of this fraction and the specified fraction
* #param f a fraction
* #return the fraction obtained by adding this fraction from the specified fraction
*/
public Fraction add(Fraction f)
{
return new Fraction(this.numerator() * f.denominator() + f.numerator() * this.denominator());
}
/**
* Compares this fraction and the specified fraction
* #param f a fraction
* #return 0 when this fraction is equal to the specified fraction; 1 when this fraction is greater than the specified
* fraction; -1 otherwise
*/
public int compareTo(Fraction f)
{
if (top > f.numerator())
return 1;
else if (top < f.numerator())
return -1;
else if (bottom > f.denominator())
return 1;
else if (bottom < f.denominator())
return -1;
else
return 0;
}
/**
* Gives the denominator of this fraction
* #return the denominator of this fraction
*/
public int denominator()
{
return bottom;
}
/**
* Gives the quotient of this fraction and the specified fraction
* #param f a fraction
* #return the fraction obtained by dividing this fraction by the specified fraction
* #throws IllegalArgumentException when the numerator equals 0
*/
public Fraction divide(Fraction f)
{
if (f.numerator() == 0) {
throw new IllegalArgumentException();
}
else
{
return new Fraction(this.numerator() * f.numerator(), this.denominator() * f.denominator());
}
}
/**
* Determines whether this fraction is equal to the specified fraction
* #param f a fraction
* #return true when this fraction is equal to the specified fraction; otherwise, false
*/
public boolean equals(Fraction f)
{
return top == f.numerator() && bottom == f.denominator();
}
/**
* Computes the greatest common divisor of the specified numbers
* #param num1 an integer
* #param num2 an integer
* #return the greatest common divisor of the specified parameters
*/
private int gcd(int num1, int num2)
{
if (num2 == 0) {
return num1;
}
else
{
return gcd(num2, num1%num2);
}
}
/**
* Calculates the product of this fraction and the specified fraction
* #param f a fraction
* #return the product of this fraction and the specified fraction
*/
public Fraction multiply(Fraction f)
{
return new Fraction(this.numerator() * f.numerator(), this.denominator() * f.denominator());
}
/**
* Simplifies this fraction by expressing its numerator and denominator in standard form:
* the denominator is positive and the numerator and denominator are relative primes
*/
public void normalize()
{
int gcd = gcd(top,bottom);
top /= gcd;
bottom /= gcd;
}
/**
* Gives the numerator of this fraction
* #return the numerator of this fraction
*/
public int numerator()
{
return top;
}
/**
* Computes the reciprocal of this fraction
* #return the reciprocal of this fraction
* #throws IllegalArgumentException when the numerator is equal to 0
*/
public Fraction reciprocal()
{
if (top == 0) {
throw new IllegalArgumentException();
}
int temp;
temp = numerator();
top = denominator();
bottom = temp;
return new Fraction(top, bottom);
}
/**
* Modifies this fraction
* #param n the new numerator of this fraction
* #param d the new denominator of this fraction
* #throws IllegalArgumentException when the denominator equals 0
*/
public void setFraction(int n, int d)
{
if (d == 0) {
throw new IllegalArgumentException();
}
top = n;
bottom = d;
}
/**
* Computes the difference of this fraction and the specified fraction
* #param f a fraction
* #return the fraction obtained by subtracting this fraction from the specified fraction
*/
public Fraction subtract(Fraction f)
{
return new Fraction(this.numerator() * f.denominator() - f.numerator() * this.denominator(), this.denominator() * f.denominator());
}
/**
* Gives a string representing this fraction in in-line notation, numerator/denominator
* #return a string representing this fraction in in-line notation, numerator/denominator
*/
#Override public String toString()
{
return String.format("%d/%d",top,bottom);
}
}
package fraction;
import java.util.Scanner;
public class FractionTester
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
System.out.print("Enter the numerator and denominator of f1 > ");
int n1 = in.nextInt(), d1 = in.nextInt();
System.out.print("Enter the numerator and denominator of f2 > ");
int n2 = in.nextInt(), d2 = in.nextInt();
System.out.print("Enter the numerator and denominator of f3 > ");
int n3 = in.nextInt(), d3 = in.nextInt();
System.out.print("Enter the numerator and denominator of f4 > ");
int n4 = in.nextInt(), d4 = in.nextInt();
System.out.println();
Fraction f1 = new Fraction(n1, d1);
Fraction f2 = new Fraction(n2, d2);
Fraction f3 = new Fraction(n3, d3);
Fraction f4 = new Fraction(n4, d4);
System.out.printf("f1 = %d", f1);
System.out.printf("f2 = %d", f2);
System.out.printf("f3 = %d", f3);
System.out.printf("f4 = %d", f4);
if (f1.compareTo(f2) == 0) {
System.out.println("f1 = f2");
}
else if (f1.compareTo(f2) < 0) {
System.out.println("f1 < f2");
}
else {
System.out.println("f1 > f2");
}
if (f3.compareTo(f4) == 0) {
System.out.println("f1 = f2");
}
else if (f3.compareTo(f4) < 0) {
System.out.println("f1 < f2");
}
else {
System.out.println("f1 > f2");
}
System.out.println();
}
}
I am trying to print the contents of the objects f1, f2, f3, and f4. It says my error is on the first print statement (System.out.printf("f1 = %d", f1);).
Your fraction is not a number (%d) but an Object of which the toString() method should be called. Change %d to %s and it will work, i.e.
System.out.printf("f1 = %s", f1);
That's not how toString() works, change:
System.out.printf("f1 = %d", f1)
to:
System.out.println("f1 = "+ f1)
When you print an object its toString() will be called, which will return a String, while you where trying to print %d (a digit).

Java Quadratic Equation Class

I have yellow squiggly lines under my coeffA = in.nextDouble(); coeffB = in.nextDouble(); and coeffC = in.nextDouble(); in my tester class and can't figure out why? Also, when I run my tester class it always returns 0.0 and -0.0 I can't seem to get any calculations at all other than 0. Any help would be appreciated!
Directions:
I have to write a program that prints all real solutions to the quadratic equation ax^2 + bx + c = 0. Read in a, b, c and use the quadratic formula. If the discriminant b^2 - 4ac is negative, display a message stating that there are no real solutions. Implement a class QuadraticEquation whose constructor receives the coefficients a, b, c of the quadratic equation. Supply methods getSolution1 and getSolution2 that get the solutions, using the quadratic formula, or 0 if no solution exists. The getSolution1 method should return the smaller of the two solutions. Supply a method boolean hasSolutions() that returns false if the discriminant is negative.
public class QuadraticEquation
{
double coeffA;
double coeffB;
double coeffC;
private boolean hasSolutions;
double discriminant;
public QuadraticEquation()
{
coeffA = 0;
coeffB = 0;
coeffC = 0;
}
/**
Constructs a quadratic equation and get 2 solutions
#param coefficientA coefficient a of quadratic equation
#param coefficientB coefficient b of quadratic equation
#param coefficientC coefficient c of quadratic equation
*/
public QuadraticEquation(double coefficientA, double coefficientB, double coefficientC)
{
coeffA = coefficientA;
coeffB = coefficientB;
coeffC = coefficientC;
discriminant = (Math.pow(coeffB, 2) - 4 * coeffA * coeffC);
}
/**
* Checks if there is a solution
* #return true if there is a real solution
*/
public boolean hasSolutions()
{
if(discriminant < 0)
hasSolutions = false;
else
hasSolutions = true;
return hasSolutions;
}
/**
* Returns the first solution to the quadratic equation
* #return the first solution
*/
public double getSolution1()
{
return (-coeffB + Math.sqrt(discriminant) / 2 * coeffA);
}
/**
* Returns the second solution to the quadratic equation
* #return the second solution
*/
public double getSolution2()
{
return (-coeffB - Math.sqrt(discriminant) / 2 * coeffA);
}
}
Here is my tester class:
import java.util.Scanner;
/**
This program tests the QuadraticEquation class.
*/
public class QuadraticEquationTester
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
System.out.print("Please enter coefficient a: ");
double coeffA = in.nextDouble();
System.out.print("Please enter coefficient b: ");
double coeffB = in.nextDouble();
System.out.print("Please enter coefficient c: ");
double coeffC = in.nextDouble();
QuadraticEquation equation = new QuadraticEquation(0, 0, 0);
if (equation.hasSolutions())
System.out.println(equation.getSolution1());
if (equation.hasSolutions());
System.out.println(equation.getSolution2());
System.exit(0);
in.close();
}
}
Your problem is that when you create the instance of the class you enter 0, 0, 0. The class creation line should be as follows:
QuadraticFormula form = new
QuadraticFormula(Coefficient A, b,..)
Sorry the formatting is weird I'm doing this on my phone. But basically put the coefficient that the user enters into the scanner input into the arguments.
You have squiggly lines under coeffA = in.nextDouble(); coeffB = in.nextDouble(); and coeffC = in.nextDouble(); because you assign to them but never use them.
You should change QuadraticEquation equation = new QuadraticEquation(0, 0, 0); to QuadraticEquation equation = new QuadraticEquation(coeffA, coeffB, coeffC);.
In the getSolution methods, the expressions have parenthesis in the wrong spots, which is causing calculations to be performed in the wrong order.
It should be
(-coeffB + Math.sqrt(discriminant)) / (2 * coeffA)
and
(-coeffB - Math.sqrt(discriminant)) / (2 * coeffA)
Your if statements are also not correct. If it has real solutions, you want to print both solutions. If not, print that it has no real solutions:
if (equation.hasSolutions()) {
System.out.println(equation.getSolution1());
System.out.println(equation.getSolution2());
}
else {
System.out.println("No real solutions.");
}

How can I modify my if statement so that the values print out after every full second?

So basically, I have a variable, time, and would like the program to print the other values for every full second.
For example if I plug in 100, it should print out 20 seconds only.
import java.util.Scanner;
public class CannonBlaster {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
final double DELTA_T = 0.01; //initiating all variables
final double G = 9.81;
double s = 0.0;
double time = 0.0;
double second = 0;
System.out.println("What's the initial velocity?: ");//asking for the initial velocity
double v =input.nextDouble();
while (s >= 0.0) //while loop is used. As long as the height isn't negative it will continue to go.
{
s += v * DELTA_T; //demonstrates the change of velocity and position for every .01 second.
v -= G * DELTA_T;
time += DELTA_T;
System.out.println("The time is: "+time+" "+(double) Math.floor(time)+" "+Math.round(time * 1000) / 1000);
second=Math.round(time * 1) / 1;
if ((double) Math.floor(time) ==time)
{
System.out.println("Approximated position: "+ s);
System.out.println("Formula's position: "+(100.0 * time - (time*time * G) / 2.0)); //prints out the formula values and the loop values.
}
}
}
Excuse the mess, it's just I've been trying different ways to get to work, but found none so far.
The problem is that double doesn't have the kind of accuracy you're looking for, so it doesn't count by an even .01 each iteration as your output clearly shows. The solution is to use BigDecimal. I rewrote the program a bit...
package test;
import java.math.BigDecimal;
import java.util.Scanner;
public class CannonBlaster {
private static final double G = 9.81;
private static final BigDecimal DELTA_T = new BigDecimal(0.01);
private static final double DELTA_T_DOUBLE = DELTA_T.doubleValue();
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
double s = 0.0;
BigDecimal time = new BigDecimal(0.0);
double time_double = 0.0;
System.out.println("What's the initial velocity?: ");// asking for the
// initial
// velocity
double v = input.nextDouble();
// As long as the height isn't negative it will continue to go.
while (s >= 0.0)
{
s += v * DELTA_T_DOUBLE;
v -= G * DELTA_T_DOUBLE;
time = time.add(DELTA_T);
time_double = time.doubleValue();
if (time.doubleValue()%1==0) {
System.out.printf("Approximated position at t=%3ds is %10.6f.\n", time.intValue(), s);
// prints out the formula values and the loop values.
System.out.println("Formula's position: " + formula(time_double));
}
}
}
private static double formula(double x){
return 100.0 * x - (x * x * G) / 2.0;
}
}
The problem is that your time step, DELTA_T, is not exactly representable as a double value. Each iteration accumulates this small error, and you can see this in the time values that get printed out.
Usually it's preferable to avoid this problem when comparing two floating point numbers by comparing the absolute difference between the two numbers to some "small" value, where "small" is defined by the problem / magnitude of numbers you are working with. DELTA_T fits pretty well here, so you could use this comparison for a per-second time step:
if (Math.abs(time - Math.round(time)) < DELTA_T)
{
// Other code here
}
Alternatively, for a more generalized time step, in PRINT_INTERVAL:
final double PRINT_INTERVAL = 0.1;
// Other code...
if (Math.abs(time / PRINT_INTERVAL - Math.round(time / PRINT_INTERVAL)) < DELTA_T)
{
// Other code here
}

Categories