Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
formatter:
trailing_commas: preserve
page_width: 80
2 changes: 2 additions & 0 deletions lib/function_tree.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@
export "src/extensions.dart" show FunctionTreeStringMethods;
export "src/trees.dart"
show FunctionTree, SingleVariableFunction, MultiVariableFunction;
export "src/complex.dart" show Complex;
export "src/complex_math.dart" show ComplexMath;
4 changes: 4 additions & 0 deletions lib/src/base.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import 'package:function_tree/src/complex.dart';

/// Base class for tree nodes.
abstract class Node {
num call(Map<String, num> variableValues);

Complex complexCall(Map<String, Complex> variableValues);

Node derivative(String variableName);

/// A TeX expression representing the node.
Expand Down
18 changes: 18 additions & 0 deletions lib/src/branches.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import "package:function_tree/src/complex.dart";

import "base.dart" show Node;
import "defs.dart" as defs;
import "derivatives.dart" show derivativesMap;
Expand All @@ -21,6 +23,10 @@ class FunctionBranch extends Branch {
num call(Map<String, num> variables) =>
defs.oneParameterFunctionMap[name]!(child(variables));

@override
Complex complexCall(Map<String, Complex> variables) =>
defs.complexOneParameterFunctionMap[name]!(child.complexCall(variables));

@override
String toTeX() => defs.oneParameterFunctionLatexRepresentation[name]!
.replaceAll("C", child.toTeX());
Expand Down Expand Up @@ -52,6 +58,10 @@ class ParenthesisBranch extends Branch {
@override
num call(Map<String, num> variables) => child(variables);

@override
Complex complexCall(Map<String, Complex> variables) =>
child.complexCall(variables);

@override
String toTeX() => r"\left(C\right)".replaceAll("C", child.toTeX());

Expand All @@ -78,6 +88,10 @@ class NegationBranch extends Branch {
@override
num call(Map<String, num> variables) => -child(variables);

@override
Complex complexCall(Map<String, Complex> variables) =>
-child.complexCall(variables);

@override
String toTeX() => "-${child.toTeX()}";

Expand All @@ -104,6 +118,10 @@ class AffirmationBranch extends Branch {
@override
num call(Map<String, num> variables) => child(variables);

@override
Complex complexCall(Map<String, Complex> variables) =>
child.complexCall(variables);

@override
String toTeX() => "+${child.toTeX()}";

Expand Down
75 changes: 75 additions & 0 deletions lib/src/complex.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import 'dart:math' as math;
import 'complex_math.dart';

class Complex {
final double real;

final double imaginary;

const Complex(this.real, this.imaginary);

Complex.polar(double magnitude, double phase)
: real = magnitude * math.cos(phase),
imaginary = magnitude * math.sin(phase);

static const zero = Complex(0, 0);

static const one = Complex(1, 0);

static const e = Complex(math.e, 0);

static const i = Complex(0, 1);

static const pi = Complex(math.pi, 0);

double get magnitude => math.sqrt(real * real + imaginary * imaginary);

double get phase => math.atan2(imaginary, real);

bool get isInfinite => real.isInfinite || imaginary.isInfinite;

bool get isNaN => real.isNaN || imaginary.isNaN;

bool get isReal => imaginary == 0;

Complex operator +(Complex other) => ComplexMath.add(this, other);

Complex operator -(Complex other) => ComplexMath.subtract(this, other);

Complex operator -() => ComplexMath.negate(this);

Complex operator *(Complex other) => ComplexMath.multiply(this, other);

Complex operator /(Complex other) => ComplexMath.divide(this, other);

Complex operator %(Complex other) => ComplexMath.modulo(this, other);

double operator [](int index) {
if (index == 0) return real;
if (index == 1) return imaginary;
throw RangeError.index(index, this, 'Index out of range: $index');
}

Complex ceil() => ComplexMath.ceil(this);

Complex floor() => ComplexMath.floor(this);

Complex round() => ComplexMath.round(this);

@override
bool operator ==(Object other) {
if (other is Complex) {
return real == other.real && imaginary == other.imaginary;
}
return false;
}

@override
int get hashCode => Object.hash(real, imaginary);
}

extension NumToComplex on num {
Complex toComplex() {
return Complex(toDouble(), 0);
}
}
Loading