Skip to content

Instantly share code, notes, and snippets.

@octylFractal
Created May 29, 2015 04:38
Show Gist options
  • Save octylFractal/5fe94541366bb1374741 to your computer and use it in GitHub Desktop.
Save octylFractal/5fe94541366bb1374741 to your computer and use it in GitHub Desktop.
All quadratics solver in Java 8 or above.
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