mirror of
https://github.com/PaddiM8/kalker.git
synced 2025-03-04 08:11:11 +01:00
Added tests for calculus.rs
This commit is contained in:
parent
33de7f034c
commit
eaf712e01f
@ -49,6 +49,22 @@ impl Identifier {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build_literal_ast(kalk_num: &crate::kalk_num::KalkNum) -> Expr {
|
||||
if kalk_num.has_imaginary() {
|
||||
Expr::Binary(
|
||||
Box::new(Expr::Literal(kalk_num.to_f64())),
|
||||
TokenKind::Plus,
|
||||
Box::new(Expr::Binary(
|
||||
Box::new(Expr::Literal(kalk_num.imaginary_to_f64())),
|
||||
TokenKind::Star,
|
||||
Box::new(Expr::Var(Identifier::from_full_name("i"))),
|
||||
)),
|
||||
)
|
||||
} else {
|
||||
Expr::Literal(kalk_num.to_f64())
|
||||
}
|
||||
}
|
||||
|
||||
fn separate_identifier_and_prime(identifier: &str) -> (String, u32) {
|
||||
let mut prim_count = 0;
|
||||
let mut pure_identifier = identifier.to_string();
|
||||
|
@ -1,3 +1,4 @@
|
||||
use crate::ast;
|
||||
use crate::ast::Expr;
|
||||
use crate::ast::Identifier;
|
||||
use crate::ast::Stmt;
|
||||
@ -14,8 +15,8 @@ pub fn derive_func(
|
||||
const H: f64 = 0.000001;
|
||||
let unit = &argument.unit.to_string();
|
||||
|
||||
let argument_with_h = Expr::Literal(argument.clone().add(context, H.into()).to_f64());
|
||||
let argument_without_h = Expr::Literal(argument.sub(context, H.into()).to_f64());
|
||||
let argument_with_h = ast::build_literal_ast(&argument.clone().add_without_unit(H.into()));
|
||||
let argument_without_h = ast::build_literal_ast(&argument.sub_without_unit(H.into()));
|
||||
let new_identifier = Identifier::from_name_and_primes(&name.pure_name, name.prime_count - 1);
|
||||
|
||||
let f_x_h = interpreter::eval_fn_call_expr(context, &new_identifier, &[argument_with_h], unit)?;
|
||||
@ -23,8 +24,8 @@ pub fn derive_func(
|
||||
interpreter::eval_fn_call_expr(context, &new_identifier, &[argument_without_h], unit)?;
|
||||
|
||||
Ok(f_x_h
|
||||
.sub(context, f_x)
|
||||
.div(context, (2f64 * H).into())
|
||||
.sub_without_unit(f_x)
|
||||
.div_without_unit((2f64 * H).into())
|
||||
.round_if_needed())
|
||||
}
|
||||
|
||||
@ -89,19 +90,7 @@ fn simpsons_rule(
|
||||
.add_without_unit(KalkNum::from(i).mul_without_unit(h.clone()));
|
||||
context.symbol_table.set(Stmt::VarDecl(
|
||||
Identifier::from_full_name(integration_variable),
|
||||
if variable_value.has_imaginary() {
|
||||
Box::new(Expr::Binary(
|
||||
Box::new(Expr::Literal(variable_value.to_f64())),
|
||||
TokenKind::Plus,
|
||||
Box::new(Expr::Binary(
|
||||
Box::new(Expr::Literal(variable_value.imaginary_to_f64())),
|
||||
TokenKind::Star,
|
||||
Box::new(Expr::Var(Identifier::from_full_name("i"))),
|
||||
)),
|
||||
))
|
||||
} else {
|
||||
Box::new(Expr::Literal(variable_value.to_f64()))
|
||||
},
|
||||
Box::new(crate::ast::build_literal_ast(&variable_value)),
|
||||
));
|
||||
|
||||
let factor = KalkNum::from(match i {
|
||||
@ -122,3 +111,154 @@ fn simpsons_rule(
|
||||
3f64 / 8f64 * h.imaginary_value,
|
||||
)))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::ast;
|
||||
use crate::calculus::Identifier;
|
||||
use crate::calculus::Stmt;
|
||||
use crate::interpreter;
|
||||
use crate::kalk_num::KalkNum;
|
||||
use crate::lexer::TokenKind::*;
|
||||
use crate::symbol_table::SymbolTable;
|
||||
use crate::test_helpers::*;
|
||||
|
||||
fn get_context<'a>(symbol_table: &'a mut SymbolTable) -> interpreter::Context<'a> {
|
||||
interpreter::Context::new(
|
||||
symbol_table,
|
||||
"",
|
||||
#[cfg(feature = "rug")]
|
||||
63u32,
|
||||
None,
|
||||
)
|
||||
}
|
||||
|
||||
fn cmp(x: f64, y: f64) -> bool {
|
||||
(x - y).abs() < 0.0001
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_derive_func() {
|
||||
let mut symbol_table = SymbolTable::new();
|
||||
let mut context = get_context(&mut symbol_table);
|
||||
context.symbol_table.insert(Stmt::FnDecl(
|
||||
Identifier::from_full_name("f"),
|
||||
vec![String::from("x")],
|
||||
binary(
|
||||
literal(2.5f64),
|
||||
Star,
|
||||
binary(var("x"), Power, literal(3f64)),
|
||||
),
|
||||
));
|
||||
|
||||
let call = Stmt::Expr(fn_call("f'", vec![*literal(12.3456f64)]));
|
||||
assert!(cmp(
|
||||
context.interpret(vec![call]).unwrap().unwrap().to_f64(),
|
||||
1143.10379f64
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_derive_complex_func() {
|
||||
let mut symbol_table = SymbolTable::new();
|
||||
let mut context = get_context(&mut symbol_table);
|
||||
context.symbol_table.insert(Stmt::FnDecl(
|
||||
Identifier::from_full_name("f"),
|
||||
vec![String::from("x")],
|
||||
binary(
|
||||
binary(
|
||||
literal(1.5f64),
|
||||
Star,
|
||||
binary(var("x"), Power, literal(2f64)),
|
||||
),
|
||||
Plus,
|
||||
binary(binary(var("x"), Power, literal(2f64)), Star, var("i")),
|
||||
),
|
||||
));
|
||||
|
||||
let call = Stmt::Expr(fn_call("f'", vec![*var("e")]));
|
||||
let result = context.interpret(vec![call]).unwrap().unwrap();
|
||||
assert!(cmp(result.to_f64(), 8.15484f64));
|
||||
assert!(cmp(result.imaginary_to_f64(), 5.43656));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_derive_func_with_complex_argument() {
|
||||
let mut symbol_table = SymbolTable::new();
|
||||
let mut context = get_context(&mut symbol_table);
|
||||
context.symbol_table.insert(Stmt::FnDecl(
|
||||
Identifier::from_full_name("f"),
|
||||
vec![String::from("x")],
|
||||
binary(
|
||||
binary(literal(3f64), Star, var("x")),
|
||||
Plus,
|
||||
binary(
|
||||
literal(0.5f64),
|
||||
Star,
|
||||
binary(var("x"), Power, literal(3f64)),
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
let result = super::derive_func(
|
||||
&mut context,
|
||||
&Identifier::from_full_name("f'"),
|
||||
KalkNum::new_with_imaginary(KalkNum::from(2f64).value, "", KalkNum::from(3f64).value),
|
||||
)
|
||||
.unwrap();
|
||||
assert!(cmp(result.to_f64(), -4.5f64) || cmp(result.to_f64(), -4.499999f64));
|
||||
assert!(cmp(result.imaginary_to_f64(), 18f64));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_integrate_with_unknown_variable() {
|
||||
let mut symbol_table = SymbolTable::new();
|
||||
let mut context = get_context(&mut symbol_table);
|
||||
let result = super::integrate_with_unknown_variable(
|
||||
&mut context,
|
||||
&*literal(2f64),
|
||||
&*literal(4f64),
|
||||
&*binary(var("x"), Star, var("dx")),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert!(cmp(result.to_f64(), 6f64));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_integrate() {
|
||||
let mut symbol_table = SymbolTable::new();
|
||||
let mut context = get_context(&mut symbol_table);
|
||||
let result = super::integrate(
|
||||
&mut context,
|
||||
&*literal(2f64),
|
||||
&*literal(4f64),
|
||||
&*var("x"),
|
||||
"x",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert!(cmp(result.to_f64(), 6f64));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_integrate_complex() {
|
||||
let mut symbol_table = SymbolTable::new();
|
||||
let mut context = get_context(&mut symbol_table);
|
||||
let result = super::integrate(
|
||||
&mut context,
|
||||
&*literal(2f64),
|
||||
&ast::build_literal_ast(&KalkNum::new_with_imaginary(
|
||||
KalkNum::from(3f64).value,
|
||||
"",
|
||||
KalkNum::from(4f64).value,
|
||||
)),
|
||||
&*binary(var("x"), Star, var("i")),
|
||||
"x",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert!(cmp(result.to_f64(), -12f64));
|
||||
assert!(cmp(result.imaginary_to_f64(), -5.5f64));
|
||||
}
|
||||
}
|
||||
|
@ -50,29 +50,13 @@ impl<'a> Context<'a> {
|
||||
Identifier::from_full_name("ans"),
|
||||
Box::new(Expr::Unit(
|
||||
num.unit.clone(),
|
||||
Box::new(Expr::Binary(
|
||||
Box::new(Expr::Literal(num.to_f64())),
|
||||
TokenKind::Plus,
|
||||
Box::new(Expr::Binary(
|
||||
Box::new(Expr::Literal(num.imaginary_to_f64())),
|
||||
TokenKind::Star,
|
||||
Box::new(Expr::Var(Identifier::from_full_name("i"))),
|
||||
)),
|
||||
)),
|
||||
Box::new(crate::ast::build_literal_ast(&num)),
|
||||
)),
|
||||
)
|
||||
} else {
|
||||
Stmt::VarDecl(
|
||||
Identifier::from_full_name("ans"),
|
||||
Box::new(Expr::Binary(
|
||||
Box::new(Expr::Literal(num.to_f64())),
|
||||
TokenKind::Plus,
|
||||
Box::new(Expr::Binary(
|
||||
Box::new(Expr::Literal(num.imaginary_to_f64())),
|
||||
TokenKind::Star,
|
||||
Box::new(Expr::Var(Identifier::from_full_name("i"))),
|
||||
)),
|
||||
)),
|
||||
Box::new(crate::ast::build_literal_ast(&num)),
|
||||
)
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user