rug_maths/
lib.rs

1pub(crate) mod complex;
2pub(crate) mod float;
3pub(crate) mod integer;
4pub(crate) mod rational;
5
6pub use complex::Complex;
7pub use float::Float;
8pub use integer::Integer;
9pub use rational::Rational;
10
11use maths_traits::{analysis, analysis::Sign};
12use num_traits::{ToPrimitive, Zero};
13
14impl Float {
15	pub fn to_rational(&self) -> Option<Rational> {
16		Some(Rational {
17			val: self.val.to_rational()?,
18		})
19	}
20}
21
22impl Complex {
23	/// Returns the real part
24	pub fn real(&self) -> Float {
25		Float {
26			val: self.val.real().clone(),
27		}
28	}
29
30	/// Returns the imaginary part
31	pub fn imag(&self) -> Float {
32		Float {
33			val: self.val.imag().clone(),
34		}
35	}
36}
37
38impl analysis::real::ComplexSubset for Float {
39	type Real = Float;
40	type Natural = Integer;
41	type Integer = Integer;
42
43	fn as_real(self) -> Self::Real {
44		self
45	}
46
47	fn as_natural(self) -> Self::Natural {
48		Self::Natural {
49			val: self.val.to_integer().unwrap().abs(),
50		}
51	}
52
53	fn as_integer(self) -> Self::Integer {
54		Self::Natural {
55			val: self.val.to_integer().unwrap(),
56		}
57	}
58
59	fn floor(self) -> Self {
60		Self {
61			val: self.val.floor(),
62		}
63	}
64
65	fn ceil(self) -> Self {
66		Self {
67			val: self.val.ceil(),
68		}
69	}
70
71	fn round(self) -> Self {
72		Self {
73			val: self.val.round(),
74		}
75	}
76
77	fn trunc(self) -> Self {
78		Self {
79			val: self.val.trunc(),
80		}
81	}
82
83	fn fract(self) -> Self {
84		Self {
85			val: self.val.fract(),
86		}
87	}
88
89	fn im(self) -> Self {
90		Self::zero()
91	}
92
93	fn re(self) -> Self {
94		self
95	}
96
97	fn conj(self) -> Self {
98		self
99	}
100}
101
102impl analysis::real::ComplexSubset for Integer {
103	type Real = Float;
104	type Natural = Integer;
105	type Integer = Integer;
106
107	fn as_real(self) -> Self::Real {
108		// ugly!
109		Float::from(self.to_i128().unwrap())
110	}
111
112	fn as_natural(self) -> Self::Natural {
113		self.abs()
114	}
115
116	fn as_integer(self) -> Self::Integer {
117		self
118	}
119
120	fn floor(self) -> Self {
121		self
122	}
123
124	fn ceil(self) -> Self {
125		self
126	}
127
128	fn round(self) -> Self {
129		self
130	}
131
132	fn trunc(self) -> Self {
133		self
134	}
135
136	fn fract(self) -> Self {
137		Self::zero()
138	}
139
140	fn im(self) -> Self {
141		Self::zero()
142	}
143
144	fn re(self) -> Self {
145		self
146	}
147
148	fn conj(self) -> Self {
149		self
150	}
151}
152
153impl analysis::real::ComplexSubset for Rational {
154	type Real = Float;
155	type Natural = Integer;
156	type Integer = Integer;
157
158	fn as_real(self) -> Self::Real {
159		Self::Real::from(self.val.to_f64())
160	}
161
162	fn as_natural(self) -> Self::Natural {
163		self.as_real().as_natural()
164	}
165
166	fn as_integer(self) -> Self::Integer {
167		self.as_real().as_integer()
168	}
169
170	fn floor(self) -> Self {
171		Self {
172			val: self.val.floor(),
173		}
174	}
175
176	fn ceil(self) -> Self {
177		Self {
178			val: self.val.ceil(),
179		}
180	}
181
182	fn round(self) -> Self {
183		Self {
184			val: self.val.round(),
185		}
186	}
187
188	fn trunc(self) -> Self {
189		Self {
190			val: self.val.trunc(),
191		}
192	}
193
194	fn fract(self) -> Self {
195		Self {
196			val: self.val.fract_trunc(rug::Integer::new()).0,
197		}
198	}
199
200	fn im(self) -> Self {
201		Self::zero()
202	}
203
204	fn re(self) -> Self {
205		self
206	}
207
208	fn conj(self) -> Self {
209		self
210	}
211}
212
213impl analysis::real::ComplexSubset for Complex {
214	type Real = Float;
215	type Natural = Integer;
216	type Integer = Integer;
217
218	fn as_real(self) -> Self::Real {
219		self.real()
220	}
221
222	fn as_natural(self) -> Self::Natural {
223		self.real().as_natural()
224	}
225
226	fn as_integer(self) -> Self::Integer {
227		self.real().as_integer()
228	}
229
230	fn floor(self) -> Self {
231		Self {
232			val: rug::Complex::with_val(self.val.prec(), {
233				let (real, imag) = self.val.into_real_imag();
234				(real.floor(), imag.floor())
235			}),
236		}
237	}
238
239	fn ceil(self) -> Self {
240		Self {
241			val: rug::Complex::with_val(self.val.prec(), {
242				let (real, imag) = self.val.into_real_imag();
243				(real.ceil(), imag.ceil())
244			}),
245		}
246	}
247
248	fn round(self) -> Self {
249		Self {
250			val: rug::Complex::with_val(self.val.prec(), {
251				let (real, imag) = self.val.into_real_imag();
252				(real.round(), imag.round())
253			}),
254		}
255	}
256
257	fn trunc(self) -> Self {
258		Self {
259			val: rug::Complex::with_val(self.val.prec(), {
260				let (real, imag) = self.val.into_real_imag();
261				(real.trunc(), imag.trunc())
262			}),
263		}
264	}
265
266	fn fract(self) -> Self {
267		Self {
268			val: rug::Complex::with_val(self.val.prec(), {
269				let (real, imag) = self.val.into_real_imag();
270				(real.fract(), imag.fract())
271			}),
272		}
273	}
274
275	fn im(self) -> Self {
276		Self {
277			val: rug::Complex::with_val(self.val.prec(), (0, self.val.into_real_imag().1)),
278		}
279	}
280
281	fn re(self) -> Self {
282		Self {
283			val: rug::Complex::with_val(self.val.prec(), (self.val.into_real_imag().0, 0)),
284		}
285	}
286
287	fn conj(self) -> Self {
288		Self {
289			val: self.val.conj(),
290		}
291	}
292}