1use std::ops::Range;
4
5pub fn nearly_eq<S, T>(x: S, y: T) -> bool
19where
20 S: Into<f64>,
21 T: Into<f64>,
22{
23 let mut b: bool = false;
24 let e = 1e-7;
25 let p: f64 = x.into().abs();
26 let q: f64 = y.into().abs();
27 if (p - q).abs() < e || (p - q).abs() / (p + q).min(f64::MAX) < e {
28 b = true;
29 }
30 b
31}
32
33#[allow(unused_comparisons)]
34pub fn tab(s: &str, space: usize) -> String {
35 let l = s.len();
36 let mut m: String = String::new();
37 let fs = format!("{}{}", " ".repeat(space - l), s);
38 m.push_str(&fs);
39 m
40}
41
42pub fn quot_rem(x: usize, y: usize) -> (i32, i32) {
43 ((x / y) as i32, (x % y) as i32)
44}
45
46pub fn choose_shorter_string(x1: String, x2: String) -> String {
50 if x1.len() > x2.len() {
51 x2
52 } else {
53 x1
54 }
55}
56
57pub fn choose_shorter_vec(x1: &Vec<f64>, x2: &Vec<f64>) -> Vec<f64> {
58 if x1.len() > x2.len() {
59 x2.clone()
60 } else {
61 x1.clone()
62 }
63}
64
65pub fn choose_longer_vec(x1: &Vec<f64>, x2: &Vec<f64>) -> Vec<f64> {
66 if x1.len() <= x2.len() {
67 x2.clone()
68 } else {
69 x1.clone()
70 }
71}
72
73pub fn max<T>(v: Vec<T>) -> T
74where
75 T: PartialOrd + Copy + Clone,
76{
77 let l = v.len();
78 if l == 1 {
79 v[0]
80 } else {
81 let mut t = if v[0] >= v[1] { v[0] } else { v[1] };
82 for i in 2..v.len() {
83 if v[i] > t {
84 t = v[i];
85 }
86 }
87 t
88 }
89}
90
91pub fn min<T>(v: Vec<T>) -> T
92where
93 T: PartialOrd + Copy + Clone,
94{
95 let l = v.len();
96 if l == 1 {
97 v[0]
98 } else {
99 let mut t = if v[0] <= v[1] { v[0] } else { v[1] };
100 for i in 2..v.len() {
101 if v[i] < t {
102 t = v[i];
103 }
104 }
105 t
106 }
107}
108
109pub fn sgn(x: usize) -> f64 {
111 if x % 2 == 0 {
112 1f64
113 } else {
114 -1f64
115 }
116}
117
118pub fn eq_vec(x: &[f64], y: &[f64], tol: f64) -> bool {
120 x.iter().zip(y.iter()).all(|(x, y)| (x - y).abs() <= tol)
121}
122
123pub fn auto_zip<T: Clone>(x: &Vec<T>) -> Vec<(T, T)> {
138 let x_head = x[0..x.len() - 1].to_vec();
139 let x_tail = x[1..x.len()].to_vec();
140 x_head.into_iter().zip(x_tail).collect()
141}
142
143pub fn find_interval<T: PartialOrd + PartialEq>(sorted_intervals: &Vec<(T, T)>, x: T) -> usize {
162 let mut i = 0;
163 let mut j = sorted_intervals.len() - 1;
164
165 assert!(
167 x >= sorted_intervals[0].0,
168 "x is smaller than the smallest interval"
169 );
170 assert!(
171 x <= sorted_intervals[sorted_intervals.len() - 1].1,
172 "x is larger than the largest interval"
173 );
174
175 while i <= j {
176 let mid = (i + j) / 2;
177 if x < sorted_intervals[mid].0 {
178 j = mid - 1;
179 } else if x > sorted_intervals[mid].1 {
180 i = mid + 1;
181 } else {
182 return mid;
183 }
184 }
185 i
186}
187
188pub fn gen_range<T: Clone + PartialOrd>(x: &[T]) -> Vec<Range<T>> {
208 let mut r = Vec::new();
209 for i in 0..x.len() - 1 {
210 r.push(Range {
211 start: x[i].clone(),
212 end: x[i + 1].clone(),
213 });
214 }
215 r
216}
217
218pub fn zip_range<T: Clone + PartialOrd, U: Clone>(x: &[T], y: &[U]) -> Vec<(Range<T>, U)> {
239 y[0..x.len() - 1]
240 .iter()
241 .enumerate()
242 .map(|(i, yi)| {
243 (
244 Range {
245 start: x[i].clone(),
246 end: x[i + 1].clone(),
247 },
248 yi.clone(),
249 )
250 })
251 .collect()
252}