Skip to content

Commit

Permalink
Add arcsin, arccos and arctan functions
Browse files Browse the repository at this point in the history
  • Loading branch information
fkleon committed Apr 14, 2019
1 parent 9121211 commit 2047d8d
Show file tree
Hide file tree
Showing 6 changed files with 268 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
### 1.1.0

- Drop support for Dart SDK versions below 2.0.0
- Add arcsin, arccos, arctan functions
- Update examples and documentation
- Switch to [pendantic](https://pub.dartlang.org/packages/pedantic) analysis
options
Expand Down
2 changes: 1 addition & 1 deletion lib/math_expressions.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* math_expressions
*
* Copyright (c) 2013-2016 Frederik Leonhardt <frederik.leonhardt@gmail.com>,
* Copyright (c) 2013-2019 Frederik Leonhardt <frederik.leonhardt@gmail.com>,
* Michael Frey <asakash117@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
Expand Down
133 changes: 122 additions & 11 deletions lib/src/functions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ class Exponential extends DefaultFunction {
return new Interval(math.exp(expEval.min), math.exp(expEval.max));
}

throw new UnimplementedError('Can not evaluate exp on $type yet.');
throw new UnimplementedError('Can not evaluate $name on $type yet.');
}
}

Expand Down Expand Up @@ -412,7 +412,7 @@ class Log extends DefaultFunction {
return asNaturalLogarithm().evaluate(type, context);
}

throw new UnimplementedError('Can not evaluate log on $type yet.');
throw new UnimplementedError('Can not evaluate $name on $type yet.');
}

@override
Expand Down Expand Up @@ -475,7 +475,7 @@ class Ln extends Log {
return new Interval(math.log(argEval.min), math.log(argEval.max));
}

throw new UnimplementedError('Can not evaluate ln on $type yet.');
throw new UnimplementedError('Can not evaluate $name on $type yet.');
}

@override
Expand Down Expand Up @@ -612,7 +612,7 @@ class Sqrt extends Root {
return new Interval(math.sqrt(argEval.min), math.sqrt(argEval.max));
}

throw new UnimplementedError('Can not evaluate sqrt on $type yet.');
throw new UnimplementedError('Can not evaluate $name on $type yet.');
}

@override
Expand Down Expand Up @@ -667,7 +667,7 @@ class Sin extends DefaultFunction {
// or just return [-1, 1] if half a period is in the given interval
}

throw new UnimplementedError('Can not evaluate sin on $type yet.');
throw new UnimplementedError('Can not evaluate $name on $type yet.');
}
}

Expand Down Expand Up @@ -719,7 +719,7 @@ class Cos extends DefaultFunction {
// or just return [-1, 1] if half a period is in the given interval
}

throw new UnimplementedError('Can not evaluate cos on $type yet.');
throw new UnimplementedError('Can not evaluate $name on $type yet.');
}
}

Expand Down Expand Up @@ -766,7 +766,7 @@ class Tan extends DefaultFunction {
//TODO apply function to all vector elements
}

throw new UnimplementedError('Can not evaluate tan on $type yet.');
throw new UnimplementedError('Can not evaluate $name on $type yet.');
}

/**
Expand All @@ -777,6 +777,117 @@ class Tan extends DefaultFunction {
Expression asSinCos() => new Sin(arg) / new Cos(arg);
}

/**
* The arcus sine function.
*/
class Asin extends DefaultFunction {
/**
* Creates a new arcus sine function with given argument expression.
*/
Asin(Expression arg) : super._unary('arcsin', arg);

/// The argument of this arcus sine function.
Expression get arg => getParam(0);

@override
Expression derive(String toVar) =>
new Number(1) / new Sqrt(new Number(1) - (arg ^ new Number(2)));

/**
* Possible simplifications:
*/
@override
Expression simplify() {
return new Asin(arg.simplify());
}

@override
dynamic evaluate(EvaluationType type, ContextModel context) {
final dynamic argEval = arg.evaluate(type, context);

if (type == EvaluationType.REAL) {
return math.asin(argEval);
}

// TODO VECTOR and INTERVAL evaluation
throw new UnimplementedError('Can not evaluate $name on $type yet.');
}
}

/**
* The arcus cosine function.
*/
class Acos extends DefaultFunction {
/**
* Creates a new arcus cosine function with given argument expression.
*/
Acos(Expression arg) : super._unary('arccos', arg);

/// The argument of this arcus cosine function.
Expression get arg => getParam(0);

@override
Expression derive(String toVar) =>
-new Number(1) / new Sqrt(new Number(1) - (arg ^ new Number(2)));

/**
* Possible simplifications:
*/
@override
Expression simplify() {
return new Acos(arg.simplify());
}

@override
dynamic evaluate(EvaluationType type, ContextModel context) {
final dynamic argEval = arg.evaluate(type, context);

if (type == EvaluationType.REAL) {
return math.acos(argEval);
}

// TODO VECTOR and INTERVAL evaluation
throw new UnimplementedError('Can not evaluate $name on $type yet.');
}
}

/**
* The arcus tangens function.
*/
class Atan extends DefaultFunction {
/**
* Creates a new arcus tangens function with given argument expression.
*/
Atan(Expression arg) : super._unary('arctan', arg);

/// The argument of this arcus tangens function.
Expression get arg => getParam(0);

@override
Expression derive(String toVar) =>
new Number(1) / (new Number(1) + (arg ^ new Number(2)));

/**
* Possible simplifications:
*/
@override
Expression simplify() {
return new Atan(arg.simplify());
}

@override
dynamic evaluate(EvaluationType type, ContextModel context) {
final dynamic argEval = arg.evaluate(type, context);

if (type == EvaluationType.REAL) {
return math.atan(argEval);
}

// TODO VECTOR and INTERVAL evaluation
throw new UnimplementedError('Can not evaluate $name on $type yet.');
}
}

/**
* The absolute value function.
*/
Expand Down Expand Up @@ -812,7 +923,7 @@ class Abs extends DefaultFunction {
//TODO apply function to all vector elements
}

throw new UnimplementedError('Can not evaluate abs on $type yet.');
throw new UnimplementedError('Can not evaluate $name on $type yet.');
}
}

Expand Down Expand Up @@ -857,7 +968,7 @@ class Ceil extends DefaultFunction {
//TODO apply function to all vector elements
}

throw new UnimplementedError('Can not evaluate ceil on $type yet.');
throw new UnimplementedError('Can not evaluate $name on $type yet.');
}
}

Expand Down Expand Up @@ -902,7 +1013,7 @@ class Floor extends DefaultFunction {
//TODO apply function to all vector elements
}

throw new UnimplementedError('Can not evaluate floor on $type yet.');
throw new UnimplementedError('Can not evaluate $name on $type yet.');
}
}

Expand Down Expand Up @@ -935,6 +1046,6 @@ class Sgn extends DefaultFunction {
if (argEval > 0) return 1.0;
}

throw new UnimplementedError('Can not evaluate sgn on $type yet.');
throw new UnimplementedError('Can not evaluate $name on $type yet.');
}
}
18 changes: 18 additions & 0 deletions lib/src/parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,15 @@ class Parser {
case TokenType.TAN:
currExpr = new Tan(exprStack.removeLast());
break;
case TokenType.ASIN:
currExpr = new Asin(exprStack.removeLast());
break;
case TokenType.ACOS:
currExpr = new Acos(exprStack.removeLast());
break;
case TokenType.ATAN:
currExpr = new Atan(exprStack.removeLast());
break;
case TokenType.ABS:
currExpr = new Abs(exprStack.removeLast());
break;
Expand Down Expand Up @@ -164,6 +173,9 @@ class Lexer {
keywords['cos'] = TokenType.COS;
keywords['sin'] = TokenType.SIN;
keywords['tan'] = TokenType.TAN;
keywords['arccos'] = TokenType.ACOS;
keywords['arcsin'] = TokenType.ASIN;
keywords['arctan'] = TokenType.ATAN;
keywords['abs'] = TokenType.ABS;
keywords['ceil'] = TokenType.CEIL;
keywords['floor'] = TokenType.FLOOR;
Expand Down Expand Up @@ -509,6 +521,12 @@ class TokenType {
const TokenType._internal('SIN', 4, function: true);
static const TokenType TAN =
const TokenType._internal('TAN', 4, function: true);
static const TokenType ACOS =
const TokenType._internal('ACOS', 4, function: true);
static const TokenType ASIN =
const TokenType._internal('ASIN', 4, function: true);
static const TokenType ATAN =
const TokenType._internal('ATAN', 4, function: true);
static const TokenType ABS =
const TokenType._internal('ABS', 4, function: true);
static const TokenType CEIL =
Expand Down
Loading

0 comments on commit 2047d8d

Please sign in to comment.