From d83106358fbf7293a112d6f3c75f6113e546aa09 Mon Sep 17 00:00:00 2001 From: Timerix22 Date: Tue, 26 Dec 2023 13:36:04 +0600 Subject: [PATCH] Math implementation --- build_c.sh | 11 +++-- build_cs.sh | 7 +++- src/Expressions/FunctionCallExpression.fu | 35 ++++++++++++++-- src/Expressions/MyMath.fu | 50 +++++++++++++++++++++++ 4 files changed, 95 insertions(+), 8 deletions(-) create mode 100644 src/Expressions/MyMath.fu diff --git a/build_c.sh b/build_c.sh index 79a1aa4..4391b3e 100755 --- a/build_c.sh +++ b/build_c.sh @@ -17,14 +17,19 @@ LINKER_ARGS="$(pkg-config --libs glib-2.0) -lm" rm -rf out bin mkdir out bin -args="-l c -D C -o "$OUT_FILE" $SRC_FILES" echo "------------[fut]------------" + +args="-l c -D C -o "$OUT_FILE" $SRC_FILES" +if [[ $1 == '--implement-math-functions' || $2 == '--implement-math-functions' ]]; then + args="$args -D IMPLEMENT_MATH_FUNCTIONS" +fi + echo fut $args fut $args -if [[ $1 != '--translate-only' ]]; then +if [[ $1 != '--translate-only' && $2 != '--translate-only' ]]; then echo "------------[gcc]------------" args="$WARNINGS $COMPILER_ARGS "$OUT_FILE" -o "$BIN_FILE" $INCLUDES $LINKER_ARGS" echo gcc $args gcc $args -fi +fi \ No newline at end of file diff --git a/build_cs.sh b/build_cs.sh index ecdaa4e..bd8705c 100755 --- a/build_cs.sh +++ b/build_cs.sh @@ -12,12 +12,17 @@ done for src_file in $SRC_FILES; do echo "---------[$src_file]---------" out_file="out/$(basename $src_file .fu).cs" + args="-l cs -D CS -n FusionCalculator $INCLUDES -o $out_file $src_file" + if [[ $1 == '--implement-math-functions' || $2 == '--implement-math-functions' ]]; then + args="$args -D IMPLEMENT_MATH_FUNCTIONS" + fi + echo fut $args fut $args done -if [[ $1 != '--translate-only' ]]; then +if [[ $1 != '--translate-only' && $2 != '--translate-only' ]]; then echo "---------[FusionCalculator.csproj]---------" args="build -c Release FusionCalculator.exe.csproj -o bin" echo dotnet $args diff --git a/src/Expressions/FunctionCallExpression.fu b/src/Expressions/FunctionCallExpression.fu index aa8e664..e2e7980 100644 --- a/src/Expressions/FunctionCallExpression.fu +++ b/src/Expressions/FunctionCallExpression.fu @@ -11,16 +11,43 @@ abstract class FunctionCallExpression : IExpression { } class FunctionCallExpressionSin : FunctionCallExpression { - internal override double FunctionImplementation(double x) => Math.Sin(x); + internal override double FunctionImplementation(double x) { +#if IMPLEMENT_MATH_FUNCTIONS + return MyMath.Sin(x); +#else + return Math.Sin(x); +#endif + } } + class FunctionCallExpressionCos : FunctionCallExpression { - internal override double FunctionImplementation(double x) => Math.Cos(x); + internal override double FunctionImplementation(double x) { +#if IMPLEMENT_MATH_FUNCTIONS + return MyMath.Cos(x); +#else + return Math.Cos(x); +#endif + } } + class FunctionCallExpressionTg : FunctionCallExpression { - internal override double FunctionImplementation(double x) => Math.Tan(x); + internal override double FunctionImplementation(double x){ +#if IMPLEMENT_MATH_FUNCTIONS + return MyMath.Tg(x); +#else + return Math.Tan(x); +#endif + } } + class FunctionCallExpressionCtg : FunctionCallExpression { - internal override double FunctionImplementation(double x) => 1 / Math.Tan(x); + internal override double FunctionImplementation(double x) { +#if IMPLEMENT_MATH_FUNCTIONS + return MyMath.Ctg(x); +#else + return 1 / Math.Tan(x); +#endif + } } class FunctionCallExpressionAsin : FunctionCallExpression { diff --git a/src/Expressions/MyMath.fu b/src/Expressions/MyMath.fu new file mode 100644 index 0000000..27c991f --- /dev/null +++ b/src/Expressions/MyMath.fu @@ -0,0 +1,50 @@ +// +// My implementation of math functions using Taylor (Maclaurin) series +// https://en.wikipedia.org/wiki/Taylor_series#List_of_Maclaurin_series_of_some_common_functions +// +public class MyMath { + /// TODO: fix fail on tg(pi/2), tg(pi*), ctg(pi*2) + static double ClampRadians(double x){ + int quotient = 0; + double pi2 = 2*Math.PI; + native { + quotient = (int)(x / pi2); + } + x -= pi2 * quotient; + return x; + } + + public static double Sin(double x){ + x = ClampRadians(x); + int iters = 16; + double pow = x; + double fact = 1; + double result = x; + for(int i = 3; i <= (2*iters+1); i+=2){ + pow *= x*x; // x power +2 + fact *= i * (i-1); // making i! from (i-2)! + fact *= -1; // change sign every iteration + result += pow/fact; + } + return result; + } + + public static double Cos(double x){ + x = ClampRadians(x); + int iters = 16; + double pow = 1; + double fact = 1; + double result = 1; + for(int i = 2; i <= (2*iters); i+=2){ + pow *= x*x; // x power +2 + fact *= i * (i-1); // making i! from (i-2)! + fact *= -1; // change sign every iteration + result += pow/fact; + } + return result; + } + + public static double Tg(double x) => Sin(x)/Cos(x); + + public static double Ctg(double x) => Cos(x)/Sin(x); +} \ No newline at end of file