Created
May 29, 2015 04:38
-
-
Save octylFractal/5fe94541366bb1374741 to your computer and use it in GitHub Desktop.
All quadratics solver in Java 8 or above.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package examples; | |
import java.util.Arrays; | |
import java.util.Iterator; | |
import java.util.Scanner; | |
public class QuadraticAndStuff { | |
private static final Complex _0 = new Complex(0, 0); | |
private static final String[] INPUTCHARS = { "a", "b", "c" }; | |
public static void main(String[] args) { | |
if (args.length == 0) { | |
args = input(); | |
} else if (args.length != 3) { | |
System.err.println("Usage: [<a> <b> <c>]"); | |
} | |
Iterator<Complex> intArgs = Arrays.stream(args) | |
.mapToDouble(Double::parseDouble) | |
.mapToObj(d -> new Complex(d, 0)).iterator(); | |
Complex a = intArgs.next(); | |
Complex b = intArgs.next(); | |
Complex c = intArgs.next(); | |
if (intArgs.hasNext()) { | |
System.err.println("Too many arguments (" + Arrays.toString(args) | |
+ ")"); | |
return; | |
} | |
Complex dsc = b.times(b).minus(new Complex(4, 0).times(a).times(c)); | |
Complex sqrt = dsc.sqrt(); | |
Complex aTimes2 = a.times(new Complex(2, 0)); | |
Complex resultPlus = _0.minus(b).plus(sqrt).div(aTimes2); | |
Complex resultMinus = _0.minus(b).minus(sqrt).div(aTimes2); | |
System.out.println(String.format( | |
"(-(%2$s)+sqrt((%2$s)^2-4*(%1$s)*(%3$s)))/(2*(%1$s))=%4$s", a, | |
b, c, resultPlus)); | |
System.out.println(String.format( | |
"(-(%2$s)-sqrt((%2$s)^2-4*(%1$s)*(%3$s)))/(2*(%1$s))=%4$s", a, | |
b, c, resultMinus)); | |
} | |
private static String[] input() { | |
@SuppressWarnings("resource") | |
Scanner s = new Scanner(System.in); | |
int[] input = new int[3]; | |
for (int i = 0; i < input.length; i++) { | |
System.out.print(INPUTCHARS[i].toUpperCase() + ": "); | |
input[i] = s.nextInt(); | |
s.nextLine(); | |
} | |
return Arrays.stream(input).mapToObj(Integer::toString) | |
.toArray(String[]::new); | |
} | |
// the real meat is below, the Complex class | |
private static final class Complex extends Number implements | |
Comparable<Complex> { | |
private final double real; | |
private final double imag; | |
/** | |
* Constructs the complex number z = u + i*v | |
* | |
* @param u | |
* Real part | |
* @param v | |
* Imaginary part | |
*/ | |
public Complex(double u, double v) { | |
real = u; | |
imag = v; | |
} | |
/** | |
* Real part of this Complex number (the x-coordinate in rectangular | |
* coordinates). | |
* | |
* @return Re[z] where z is this Complex number. | |
*/ | |
public double real() { | |
return real; | |
} | |
/** | |
* Imaginary part of this Complex number (the y-coordinate in | |
* rectangular coordinates). | |
* | |
* @return Im[z] where z is this Complex number. | |
*/ | |
public double imag() { | |
return imag; | |
} | |
/** | |
* Modulus of this Complex number (the distance from the origin in polar | |
* coordinates). | |
* | |
* @return |z| where z is this Complex number. | |
*/ | |
public double mod() { | |
if (Double.compare(real, 0) != 0 || Double.compare(imag, 0) != 0) { | |
return Math.sqrt(real * real + imag * imag); | |
} else { | |
return 0d; | |
} | |
} | |
/** | |
* Argument of this Complex number (the angle in radians with the x-axis | |
* in polar coordinates). | |
* | |
* @return arg(z) where z is this Complex number. | |
*/ | |
public double arg() { | |
return Math.atan2(imag, real); | |
} | |
/** | |
* Complex conjugate of this Complex number (the conjugate of x+i*y is | |
* x-i*y). | |
* | |
* @return z-bar where z is this Complex number. | |
*/ | |
public Complex conj() { | |
return new Complex(real, -imag); | |
} | |
/** | |
* Addition of Complex numbers (doesn't change this Complex number). <br> | |
* (x+i*y) + (s+i*t) = (x+s)+i*(y+t). | |
* | |
* @param w | |
* is the number to add. | |
* @return z+w where z is this Complex number. | |
*/ | |
public Complex plus(Complex w) { | |
return new Complex(real + w.real(), imag + w.imag()); | |
} | |
/** | |
* Subtraction of Complex numbers (doesn't change this Complex number). <br> | |
* (x+i*y) - (s+i*t) = (x-s)+i*(y-t). | |
* | |
* @param w | |
* is the number to subtract. | |
* @return z-w where z is this Complex number. | |
*/ | |
public Complex minus(Complex w) { | |
return new Complex(real - w.real(), imag - w.imag()); | |
} | |
/** | |
* Complex multiplication (doesn't change this Complex number). | |
* | |
* @param w | |
* is the number to multiply by. | |
* @return z*w where z is this Complex number. | |
*/ | |
public Complex times(Complex w) { | |
return new Complex(real * w.real() - imag * w.imag(), real | |
* w.imag() + imag * w.real()); | |
} | |
/** | |
* Division of Complex numbers (doesn't change this Complex number). <br> | |
* (x+i*y)/(s+i*t) = ((x*s+y*t) + i*(y*s-y*t)) / (s^2+t^2) | |
* | |
* @param w | |
* is the number to divide by | |
* @return new Complex number z/w where z is this Complex number | |
*/ | |
public Complex div(Complex w) { | |
double den = Math.pow(w.mod(), 2); | |
return new Complex((real * w.real() + imag * w.imag()) / den, (imag | |
* w.real() - real * w.imag()) | |
/ den); | |
} | |
/** | |
* Complex exponential (doesn't change this Complex number). | |
* | |
* @return exp(z) where z is this Complex number. | |
*/ | |
public Complex exp() { | |
return new Complex(Math.exp(real) * Math.cos(imag), Math.exp(real) | |
* Math.sin(imag)); | |
} | |
/** | |
* Principal branch of the Complex logarithm of this Complex number. | |
* (doesn't change this Complex number). The principal branch is the | |
* branch with -pi < arg <= pi. | |
* | |
* @return log(z) where z is this Complex number. | |
*/ | |
public Complex log() { | |
return new Complex(Math.log(this.mod()), this.arg()); | |
} | |
/** | |
* Complex square root (doesn't change this complex number). Computes | |
* the principal branch of the square root, which is the value with 0 <= | |
* arg < pi. | |
* | |
* @return sqrt(z) where z is this Complex number. | |
*/ | |
public Complex sqrt() { | |
double r = Math.sqrt(this.mod()); | |
double theta = this.arg() / 2; | |
return new Complex(r * Math.cos(theta), r * Math.sin(theta)); | |
} | |
// Real cosh function (used to compute complex trig functions) | |
private double cosh(double theta) { | |
return (Math.exp(theta) + Math.exp(-theta)) / 2; | |
} | |
// Real sinh function (used to compute complex trig functions) | |
private double sinh(double theta) { | |
return (Math.exp(theta) - Math.exp(-theta)) / 2; | |
} | |
/** | |
* Sine of this Complex number (doesn't change this Complex number). <br> | |
* sin(z) = (exp(i*z)-exp(-i*z))/(2*i). | |
* | |
* @return sin(z) where z is this Complex number. | |
*/ | |
public Complex sin() { | |
return new Complex(cosh(imag) * Math.sin(real), sinh(imag) | |
* Math.cos(real)); | |
} | |
/** | |
* Cosine of this Complex number (doesn't change this Complex number). <br> | |
* cos(z) = (exp(i*z)+exp(-i*z))/ 2. | |
* | |
* @return cos(z) where z is this Complex number. | |
*/ | |
public Complex cos() { | |
return new Complex(cosh(imag) * Math.cos(real), -sinh(imag) | |
* Math.sin(real)); | |
} | |
/** | |
* Hyperbolic sine of this Complex number (doesn't change this Complex | |
* number). <br> | |
* sinh(z) = (exp(z)-exp(-z))/2. | |
* | |
* @return sinh(z) where z is this Complex number. | |
*/ | |
public Complex sinh() { | |
return new Complex(sinh(real) * Math.cos(imag), cosh(real) | |
* Math.sin(imag)); | |
} | |
/** | |
* Hyperbolic cosine of this Complex number (doesn't change this Complex | |
* number). <br> | |
* cosh(z) = (exp(z) + exp(-z)) / 2. | |
* | |
* @return cosh(z) where z is this Complex number. | |
*/ | |
public Complex cosh() { | |
return new Complex(cosh(real) * Math.cos(imag), sinh(real) | |
* Math.sin(imag)); | |
} | |
/** | |
* Tangent of this Complex number (doesn't change this Complex number). <br> | |
* tan(z) = sin(z)/cos(z). | |
* | |
* @return tan(z) where z is this Complex number. | |
*/ | |
public Complex tan() { | |
return (this.sin()).div(this.cos()); | |
} | |
/** | |
* Negative of this complex number (chs stands for change sign). This | |
* produces a new Complex number and doesn't change this Complex number. <br> | |
* -(x+i*y) = -x-i*y. | |
* | |
* @return -z where z is this Complex number. | |
*/ | |
public Complex chs() { | |
return new Complex(-real, -imag); | |
} | |
/** | |
* String representation of this Complex number. | |
* | |
* @return x+i*y, x-i*y, x, or i*y as appropriate. | |
*/ | |
@Override | |
public String toString() { | |
if (Double.compare(real, 0) != 0 && Double.compare(imag, 0) > 0) { | |
return real + " + " + imag + "i"; | |
} | |
if (Double.compare(real, 0) != 0 && Double.compare(imag, 0) < 0) { | |
return real + " - " + (-imag) + "i"; | |
} | |
if (Double.compare(imag, 0) == 0) { | |
return String.valueOf(real); | |
} | |
if (Double.compare(real, 0) == 0) { | |
return imag + "i"; | |
} | |
// shouldn't get here (unless Inf or NaN) | |
return real + " + i*" + imag; | |
} | |
@Override | |
public int intValue() { | |
if (Double.compare(imag, 0) != 0) { | |
throw new UnsupportedOperationException("not real"); | |
} | |
return (int) real; | |
} | |
@Override | |
public long longValue() { | |
if (Double.compare(imag, 0) != 0) { | |
throw new UnsupportedOperationException("not real"); | |
} | |
return (long) real; | |
} | |
@Override | |
public float floatValue() { | |
if (Double.compare(imag, 0) != 0) { | |
throw new UnsupportedOperationException("not real"); | |
} | |
return (float) real; | |
} | |
@Override | |
public double doubleValue() { | |
if (Double.compare(imag, 0) != 0) { | |
throw new UnsupportedOperationException("not real"); | |
} | |
return real; | |
} | |
@Override | |
public int compareTo(Complex o) { | |
return Double.compare(mod() - o.mod(), 0); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment