pub fn has_brackets(s: &str) -> bool {
let mut stack = Vec::new();
let mut has_brackets = false;
for c in s.chars() {
match c {
'(' | '{' | '[' => {
stack.push(c);
has_brackets = true;
}
')' => {
if stack.pop() != Some('(') {
return false;
}
has_brackets = true
}
'}' => {
if stack.pop() != Some('{') {
return false;
}
has_brackets = true;
}
']' => {
if stack.pop() != Some('[') {
return false;
}
has_brackets = true;
}
_ => {}
}
}
has_brackets && stack.is_empty()
}
pub fn any_brackets(s: &str) -> bool {
!s.chars()
.any(|c| c == '(' || c == '{' || c == '[' || c == ')' || c == '}' || c == ']')
}
pub fn find_char_positions(input: &str, target_char: char) -> Vec<usize> {
let mut positions = Vec::new();
let mut start_pos = 0;
while let Some(pos) = input[start_pos..].find(target_char) {
positions.push(start_pos + pos);
start_pos += pos + 1;
}
positions
}
pub fn find_char_positions_but_not_inside_brackets(input: &str, target_char: char) -> Vec<usize> {
let mut positions = Vec::new();
let mut start_pos = 0;
let mut inside_brackets = false;
while let Some(pos) = input[start_pos..].find(target_char) {
let char_index = start_pos + pos;
if !inside_brackets {
if let Some(opening_bracket) = input[..char_index]
.chars()
.rfind(|c| c == &'(' || c == &'{' || c == &'[')
{
if let Some(closing_bracket) = input[char_index..]
.chars()
.find(|c| c == &')' || c == &'}' || c == &']')
{
if opening_bracket == '(' && closing_bracket == ')'
|| opening_bracket == '{' && closing_bracket == '}'
|| opening_bracket == '[' && closing_bracket == ']'
{
inside_brackets = true;
}
}
} else {
positions.push(char_index);
}
}
start_pos += pos + 1;
}
positions
}
pub fn find_char_positions_outside_brackets(s: &str, c: char) -> Option<usize> {
let mut stack = Vec::new();
let mut positions = Vec::new();
let _positions_sorted: Vec<usize> = Vec::new();
for (i, ch) in s.chars().enumerate() {
if ch == '(' {
stack.push(i);
} else if ch == ')' {
if let Some(_) = stack.pop() {
}
} else if ch == c && stack.is_empty() {
positions.push(i);
}
}
let res = if positions.is_empty() {
None
} else {
let pos = *positions.first().unwrap();
Some(pos)
};
res
}
pub fn find_pair_to_this_bracket(input: &str, bracket_start: usize) -> usize {
let mut stack = bracket_start;
let mut bracket_end = None;
for (i, c) in input.chars().enumerate() {
if c == '(' {
stack += 1;
} else if c == ')' {
stack -= 1;
if stack == 0 {
bracket_end = Some(i);
break;
}
}
} bracket_end.unwrap()
}
pub fn linspace(start: f64, end: f64, num_values: usize) -> Vec<f64> {
let mut values = Vec::with_capacity(num_values);
let step = (end - start) / (num_values as f64 - 1.0);
for i in 0..num_values {
let value = start + (i as f64 * step);
values.push(value);
}
values
}
pub fn numerical_derivative<F>(f: F, x_values: Vec<f64>, h: f64) -> Vec<f64>
where
F: Fn(f64) -> f64,
{
let mut derivatives = Vec::with_capacity(x_values.len());
for &x in &x_values {
let f_x_plus_h = f(x + h);
let f_x_minus_h = f(x - h);
let derivative = (f_x_plus_h - f_x_minus_h) / (2.0 * h);
derivatives.push(derivative);
}
derivatives
}
pub fn numerical_derivative_multi<F>(f: F, x_values: Vec<f64>, h: f64) -> Vec<f64>
where
F: Fn(Vec<f64>) -> f64,
{
let mut derivatives = Vec::with_capacity(x_values.len());
for i in 0..x_values.len() {
let mut x_plus_h = x_values.clone();
let mut x_minus_h = x_values.clone();
x_plus_h[i] += h;
x_minus_h[i] -= h;
let f_x_plus_h = f(x_plus_h);
let f_x_minus_h = f(x_minus_h);
let derivative = (f_x_plus_h - f_x_minus_h) / (2.0 * h);
derivatives.push(derivative);
}
derivatives
}
pub fn norm(x: Vec<f64>, y: Vec<f64>) -> f64 {
assert_eq!(x.len(), y.len());
let norm_res = (1.0 / x.len() as f64)
* x.iter()
.zip(y.iter())
.map(|(a, b)| (a - b).powi(2))
.sum::<f64>()
.sqrt();
norm_res
}
pub fn transpose<T>(v: Vec<Vec<T>>) -> Vec<Vec<T>> {
assert!(!v.is_empty());
let len = v[0].len();
let mut iters: Vec<_> = v
.into_iter()
.map(std::iter::IntoIterator::into_iter)
.collect();
(0..len)
.map(|_| iters.iter_mut().map(|n| n.next().unwrap()).collect())
.collect()
}
pub fn unbox<T>(value: Box<T>) -> T {
*value
}