add lab 09 Complex
This commit is contained in:
3 files changed
+423
No files matched your search
@@ -0,0 +1,196 @@
|
||||
package ca.bcit.comp1510.lab09;
|
||||
|
||||
/**
|
||||
* Immutable Complex number type.
|
||||
* @author blink
|
||||
* @version 2025
|
||||
* @param re Real part of number.
|
||||
* @param im Imaginary part of number.
|
||||
*/
|
||||
public record Complex(double re, double im) {
|
||||
|
||||
/** Imaginary number I. */
|
||||
public static final Complex I = new Complex(0, 1);
|
||||
|
||||
/** Complex number 0. */
|
||||
public static final Complex ZERO = new Complex(0, 0);
|
||||
|
||||
/** Complex number 1. */
|
||||
public static final Complex ONE = new Complex(1, 0);
|
||||
|
||||
/**
|
||||
* Factory method for complex number in polar form.
|
||||
* @param radius magnitude of number
|
||||
* @param angle argument of number
|
||||
* @return corresponding Complex number
|
||||
*/
|
||||
public static Complex polarComplex(double radius, double angle) {
|
||||
|
||||
return new Complex(radius * Math.cos(angle),
|
||||
radius * Math.sin(angle));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns absolute value of this.
|
||||
* @return the absolute value
|
||||
*/
|
||||
public double abs() {
|
||||
return Math.hypot(re, im);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns argument of this, the angle with respect to
|
||||
* the positive real axis in range -π to π.
|
||||
* @return the argument, in radians
|
||||
*/
|
||||
public double arg() {
|
||||
return Math.atan2(im, re);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns conjugate value of this.
|
||||
* @return the conjugate value
|
||||
*/
|
||||
public Complex conjugate() {
|
||||
return new Complex(re, -im);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds parameter to this complex number.
|
||||
* @param op2 complex number to add
|
||||
* @return sum of this + op2
|
||||
*/
|
||||
public Complex add(Complex op2) {
|
||||
return new Complex(re + op2.re, im + op2.im);
|
||||
}
|
||||
|
||||
/**
|
||||
* real add.
|
||||
* @param op2 real value to add
|
||||
* @return result
|
||||
*/
|
||||
public Complex add(double op2) {
|
||||
return new Complex(re + op2, im);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts parameter from this complex number.
|
||||
* @param op2 complex number to subtract
|
||||
* @return difference of this - op2
|
||||
*/
|
||||
public Complex subtract(Complex op2) {
|
||||
return new Complex(re - op2.re, im - op2.im);
|
||||
}
|
||||
|
||||
/**
|
||||
* real subtract.
|
||||
* @param op2 real value to subtract
|
||||
* @return result
|
||||
*/
|
||||
public Complex subtract(double op2) {
|
||||
return new Complex(re - op2, im);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies parameter with this complex number.
|
||||
* @param op2 complex number to multiply
|
||||
* @return product of this * op2
|
||||
*/
|
||||
public Complex multiply(Complex op2) {
|
||||
double realPart = re * op2.re - im * op2.im;
|
||||
double imagPart = re * op2.im + im * op2.re;
|
||||
return new Complex(realPart, imagPart);
|
||||
}
|
||||
|
||||
/**
|
||||
* scalar multiply.
|
||||
* @param op2 scalar value to multiply
|
||||
* @return result
|
||||
*/
|
||||
public Complex multiply(double op2) {
|
||||
return new Complex(re * op2, im * op2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns reciprocal of this complex number.
|
||||
* @return 1 / this
|
||||
*/
|
||||
public Complex reciprocal() {
|
||||
double denominator = re * re + im * im;
|
||||
if (denominator == 0.0) {
|
||||
throw new IllegalArgumentException(
|
||||
"tried to take reciprocal of 0");
|
||||
}
|
||||
return new Complex(re / denominator, -im / denominator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Divides parameter into this complex number.
|
||||
* @param op2 complex number to divide
|
||||
* @return quotient of this / op2
|
||||
*/
|
||||
public Complex divide(Complex op2) {
|
||||
if (op2.re == 0.0 && op2.im == 0.0) {
|
||||
throw new IllegalArgumentException("Tried to divide by zero");
|
||||
}
|
||||
return multiply(op2.reciprocal());
|
||||
}
|
||||
|
||||
/**
|
||||
* scalar divide.
|
||||
* @param op2 scalar value to divide
|
||||
* @return result
|
||||
*/
|
||||
public Complex divide(double op2) {
|
||||
if (op2 == 0.0) {
|
||||
throw new IllegalArgumentException("Tried to divide by 0.0");
|
||||
}
|
||||
return new Complex(re / op2, im);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return complex square root of this.
|
||||
* @return the square root
|
||||
*/
|
||||
public Complex sqrt() {
|
||||
return polarComplex(Math.sqrt(this.abs()), this.arg() / 2.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the exponential e to the power of this,
|
||||
* where e is Euler's constant Math.E.
|
||||
* @return e to the power this
|
||||
*/
|
||||
public Complex exp() {
|
||||
return new Complex(Math.exp(re) * Math.cos(im),
|
||||
Math.exp(re) * Math.sin(im));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the natural logarithm of this,
|
||||
* with argument in range -π to π.
|
||||
* @return e to the power this
|
||||
*/
|
||||
public Complex log() {
|
||||
return new Complex(Math.log(abs()), arg());
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts to string with special cases for real and imaginary
|
||||
* values.
|
||||
* @return String representation of the complex number
|
||||
*/
|
||||
public String toString() {
|
||||
if (im == 0.0) {
|
||||
return Double.toString(re);
|
||||
} else if (re == 0.0) {
|
||||
return Double.toString(im) + "i";
|
||||
} else if (im > 0) {
|
||||
return Double.toString(re) + " + "
|
||||
+ Double.toString(im) + "i";
|
||||
} else {
|
||||
return Double.toString(re) + " - "
|
||||
+ Double.toString(-im) + "i";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package ca.bcit.comp1510.lab09;
|
||||
|
||||
/**
|
||||
* Driver to exercise the use of multiple Complex objects. Includes tests for
|
||||
* divide by zero cases
|
||||
*
|
||||
* @author Lewis & Loftus 9e
|
||||
* @author BCIT
|
||||
* @version 2017
|
||||
*/
|
||||
public class ComplexTester {
|
||||
|
||||
/** 3 + 4 I real part. */
|
||||
private static final int TEST1R = 3;
|
||||
|
||||
/** 3 + 4 I imaginary part. */
|
||||
private static final int TEST1I = 4;
|
||||
|
||||
/** 1 + I real part. */
|
||||
private static final int TEST2R = 1;
|
||||
|
||||
/** 1 + I imaginary part. */
|
||||
private static final int TEST2I = 1;
|
||||
|
||||
/**
|
||||
* Creates some complex number objects and performs various operations on
|
||||
* them.
|
||||
*
|
||||
* @param args command-line arguments (unused)
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
Complex z1 = new Complex(TEST1R, TEST1I);
|
||||
Complex z2 = new Complex(TEST2R, TEST2I);
|
||||
Complex z3;
|
||||
Complex z4;
|
||||
Complex z5;
|
||||
Complex z6;
|
||||
Complex z7;
|
||||
System.out.println("First complex number: " + z1);
|
||||
System.out.println("Second complex number: " + z2);
|
||||
|
||||
if (z1.equals(z2)) {
|
||||
System.out.println("z1 and z2 are equal.");
|
||||
} else {
|
||||
System.out.println("z1 and z2 are NOT equal.");
|
||||
}
|
||||
|
||||
z3 = z1.reciprocal();
|
||||
System.out.println("The reciprocal of z1 is: " + z3);
|
||||
|
||||
z4 = z1.add(z2);
|
||||
z5 = z1.subtract(z2);
|
||||
z6 = z1.multiply(z2);
|
||||
z7 = z1.divide(z2);
|
||||
|
||||
System.out.println("z1 + z2: " + z4);
|
||||
System.out.println("z1 - z2: " + z5);
|
||||
System.out.println("z1 * z2: " + z6);
|
||||
System.out.println("z1 / z2: " + z7);
|
||||
System.out.println("One = " + Complex.ONE + "\nZero = "
|
||||
+ Complex.ZERO + "\nI = " + Complex.I
|
||||
+ "\nI * I = " + Complex.I.multiply(Complex.I));
|
||||
|
||||
testFunctions(z1, z2);
|
||||
|
||||
testErrorCases();
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Groups together error test cases.
|
||||
private static void testErrorCases() {
|
||||
try {
|
||||
Complex.ZERO.reciprocal();
|
||||
System.out.println("ZERO reciprocal test failed");
|
||||
} catch (IllegalArgumentException ex) {
|
||||
System.out.println("ZERO reciprocal test worked");
|
||||
}
|
||||
try {
|
||||
Complex.ONE.divide(Complex.ZERO);
|
||||
System.out.println("Divide by zero test failed");
|
||||
} catch (IllegalArgumentException ex) {
|
||||
System.out.println("Divide by zero test worked");
|
||||
}
|
||||
}
|
||||
|
||||
// Test other Complex functions.
|
||||
private static void testFunctions(Complex z1, Complex z2) {
|
||||
final double piDiv4 = Math.PI / 4.0;
|
||||
final Complex minusOne = Complex.ZERO.subtract(Complex.ONE);
|
||||
final Complex pi = new Complex(0.0, Math.PI);
|
||||
System.out.println("abs(" + z1 + ") = " + z1.abs()
|
||||
+ "\nabs(" + Complex.I + ") = " + Complex.I.abs()
|
||||
+ "\narg(" + z2 + ") = " + z2.arg()
|
||||
+ "\npi / 4 = " + piDiv4
|
||||
+ "\narg(" + Complex.I + ") = " + Complex.I.arg()
|
||||
+ "\npi / 2 = " + Math.PI / 2.0
|
||||
+ "\narg(" + minusOne + ") = " + minusOne.arg()
|
||||
+ "\npi / 2 = " + Math.PI
|
||||
+ "\nconjugate(" + z1 + ") = " + z1.conjugate()
|
||||
+ "\nexp(" + z1 + ") = " + z1.exp()
|
||||
+ "\nlog(" + z1 + ") = " + z1.log()
|
||||
+ "\nexp(log(" + z1 + ")) = " + z1.log().exp()
|
||||
+ "\nlog(exp(" + z1 + ")) = " + z1.exp().log()
|
||||
+ "\nexp(" + z2 + ") = " + z2.exp()
|
||||
+ "\nlog(" + z2 + ") = " + z2.log()
|
||||
+ "\nexp(log(" + z2 + ")) = " + z2.log().exp()
|
||||
+ "\nlog(exp(" + z2 + ")) = " + z2.exp().log()
|
||||
+ "\nexp(πi) + 1 = " + pi.exp().add(Complex.ONE)
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
package ca.bcit.comp1510.lab09;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class ComplexTest {
|
||||
Complex c1 = new Complex(3, 4);
|
||||
Complex c2 = new Complex(0, 1);
|
||||
Complex c3 = new Complex(1, 1);
|
||||
|
||||
@Test
|
||||
void testPolarComplex() {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAbs() {
|
||||
assertEquals(5, c1.abs());
|
||||
assertNotEquals(1, c1.abs());
|
||||
assertEquals(1, c2.abs());
|
||||
assertNotEquals(5, c2.abs());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testArg() {
|
||||
assertEquals(0.7853981633974483, c3.arg());
|
||||
assertNotEquals(0.03532358293, c3.arg());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConjugate() {
|
||||
assertEquals(new Complex(3, -4), c1.conjugate());
|
||||
assertNotEquals(new Complex(3, 4), c1.conjugate());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAddComplex() {
|
||||
assertEquals(new Complex(4, 5), c1.add(c3));
|
||||
assertNotEquals(new Complex(1, 3), c1.add(c3));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAddDouble() {
|
||||
assertEquals(new Complex(8, 4), c1.add( 5.0));
|
||||
assertNotEquals(new Complex(3, 6), c2.add(4.0));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSubtractComplex() {
|
||||
assertEquals(new Complex(2, 3), c1.subtract(c3));
|
||||
assertNotEquals(new Complex(4, 3), c1.subtract(c2));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSubtractDouble() {
|
||||
assertEquals(new Complex(2, 4), c1.subtract(1.0));
|
||||
assertNotEquals(new Complex(4, 3), c1.subtract(3.0));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMultiplyComplex() {
|
||||
assertEquals(new Complex(-1, 7), c1.multiply(c3));
|
||||
assertNotEquals(new Complex(4, 3), c1.multiply(c3));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMultiplyDouble() {
|
||||
assertEquals(new Complex(6, 8), c1.multiply(2.0));
|
||||
assertNotEquals(new Complex(5, 6), c2.multiply(3));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReciprocal() {
|
||||
assertEquals(new Complex(3.0/25, -4.0/25), c1.reciprocal());
|
||||
assertNotEquals(new Complex(3.0/25, -4.0/25), c2.reciprocal());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDivideComplex() {
|
||||
assertEquals(new Complex(3.5, 0.5), c1.divide(c3));
|
||||
assertNotEquals(new Complex(-0.5, 3.5), c1.divide(c3));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDivideDouble() {
|
||||
assertEquals(new Complex(1.5, 4), c1.divide(2.0));
|
||||
assertNotEquals(new Complex(2, 4), c1.divide(1.0));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSqrt() {
|
||||
assertEquals(new Complex(2, 1), c1.sqrt());
|
||||
assertNotEquals(new Complex(1, 2), c1.sqrt());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExp() {
|
||||
assertEquals(new Complex(-13.128783081462158, -15.200784463067954), c1.exp());
|
||||
assertNotEquals(new Complex(1, 2), c1.exp());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLog() {
|
||||
assertEquals(new Complex(1.6094379124341003, 0.9272952180016122), c1.log());
|
||||
assertNotEquals(new Complex(1, 2), c1.log());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testToString() {
|
||||
assertEquals("3.0 + 4.0i", c1.toString());
|
||||
assertNotEquals("3 + 4i", c1.toString());
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user