mathhook_core/functions/elementary/
logarithmic.rs1use crate::core::{Expression, Symbol};
6use crate::functions::properties::*;
7use std::collections::HashMap;
8use std::sync::Arc;
9
10pub struct LogarithmicIntelligence {
14 properties: HashMap<String, FunctionProperties>,
16}
17
18impl Default for LogarithmicIntelligence {
19 fn default() -> Self {
20 Self::new()
21 }
22}
23
24impl LogarithmicIntelligence {
25 pub fn new() -> Self {
27 let mut intelligence = Self {
28 properties: HashMap::with_capacity(4),
29 };
30
31 intelligence.initialize_ln();
32 intelligence.initialize_log();
33
34 intelligence
35 }
36
37 pub fn get_properties(&self) -> HashMap<String, FunctionProperties> {
39 self.properties.clone()
40 }
41
42 pub fn has_function(&self, name: &str) -> bool {
44 self.properties.contains_key(name)
45 }
46
47 fn initialize_ln(&mut self) {
49 self.properties.insert(
51 "ln".to_owned(),
52 FunctionProperties::Elementary(Box::new(ElementaryProperties {
53 derivative_rule: Some(DerivativeRule {
55 rule_type: DerivativeRuleType::Custom {
56 builder: Arc::new(|arg: &Expression| {
57 Expression::pow(arg.clone(), Expression::integer(-1))
58 }),
59 },
60 result_template: "1/x".to_owned(),
61 }),
62 antiderivative_rule: Some(AntiderivativeRule {
63 rule_type: AntiderivativeRuleType::Custom {
64 builder: Arc::new(|var: Symbol| {
65 Expression::add(vec![
66 Expression::mul(vec![
67 Expression::symbol(var.clone()),
68 Expression::function(
69 "ln",
70 vec![Expression::symbol(var.clone())],
71 ),
72 ]),
73 Expression::mul(vec![
74 Expression::integer(-1),
75 Expression::symbol(var),
76 ]),
77 ])
78 }),
79 },
80 result_template: "∫ln(x)dx = x·ln(x) - x + C".to_owned(),
81 constant_handling: ConstantOfIntegration::AddConstant,
82 }),
83
84 special_values: vec![
86 SpecialValue {
88 input: "1".to_owned(),
89 output: Expression::integer(0),
90 latex_explanation: "\\ln(1) = 0".to_owned(),
91 },
92 SpecialValue {
94 input: "e".to_owned(),
95 output: Expression::integer(1),
96 latex_explanation: "\\ln(e) = 1".to_owned(),
97 },
98 ],
99
100 identities: Box::new(vec![
102 MathIdentity {
104 name: "Logarithm Product Law".to_owned(),
105 lhs: Expression::function(
106 "ln",
107 vec![Expression::mul(vec![
108 Expression::symbol("x"),
109 Expression::symbol("y"),
110 ])],
111 ),
112 rhs: Expression::add(vec![
113 Expression::function("ln", vec![Expression::symbol("x")]),
114 Expression::function("ln", vec![Expression::symbol("y")]),
115 ]),
116 conditions: vec!["x, y > 0".to_owned()],
117 },
118 ]),
119
120 domain_range: Box::new(DomainRangeData {
121 domain: Domain::Interval(Expression::integer(0), Expression::symbol("∞")), range: Range::Real, singularities: vec![Expression::integer(0)], }),
125
126 periodicity: None,
128 wolfram_name: Some("Log"),
129 })),
130 );
131 }
132
133 fn initialize_log(&mut self) {
135 self.properties.insert(
136 "log".to_owned(),
137 FunctionProperties::Elementary(Box::new(ElementaryProperties {
138 derivative_rule: Some(DerivativeRule {
139 rule_type: DerivativeRuleType::Custom {
140 builder: Arc::new(|arg: &Expression| {
141 Expression::mul(vec![
142 Expression::pow(arg.clone(), Expression::integer(-1)),
143 Expression::pow(
144 Expression::function("ln", vec![Expression::integer(10)]),
145 Expression::integer(-1),
146 ),
147 ])
148 }),
149 },
150 result_template: "1/(x·ln(10))".to_owned(),
151 }),
152 antiderivative_rule: Some(AntiderivativeRule {
153 rule_type: AntiderivativeRuleType::Custom {
154 builder: Arc::new(|var: Symbol| {
155 Expression::mul(vec![
156 Expression::pow(
157 Expression::function("ln", vec![Expression::integer(10)]),
158 Expression::integer(-1),
159 ),
160 Expression::add(vec![
161 Expression::mul(vec![
162 Expression::symbol(var.clone()),
163 Expression::function(
164 "ln",
165 vec![Expression::symbol(var.clone())],
166 ),
167 ]),
168 Expression::mul(vec![
169 Expression::integer(-1),
170 Expression::symbol(var),
171 ]),
172 ]),
173 ])
174 }),
175 },
176 result_template: "∫log(x)dx = (1/ln(10))·(x·ln(x) - x) + C".to_owned(),
177 constant_handling: ConstantOfIntegration::AddConstant,
178 }),
179 special_values: vec![
180 SpecialValue {
181 input: "1".to_owned(),
182 output: Expression::integer(0),
183 latex_explanation: "\\log(1) = 0".to_owned(),
184 },
185 SpecialValue {
186 input: "10".to_owned(),
187 output: Expression::integer(1),
188 latex_explanation: "\\log(10) = 1".to_owned(),
189 },
190 ],
191 identities: Box::new(vec![]),
192 domain_range: Box::new(DomainRangeData {
193 domain: Domain::Interval(Expression::integer(0), Expression::symbol("∞")),
194 range: Range::Real,
195 singularities: vec![Expression::integer(0)],
196 }),
197 periodicity: None,
198 wolfram_name: Some("Log"),
199 })),
200 );
201 }
202}