polars_ops/series/ops/
linear_space.rs1use polars_core::prelude::*;
2use polars_core::series::IsSorted;
3#[cfg(feature = "serde")]
4use serde::{Deserialize, Serialize};
5use strum_macros::IntoStaticStr;
6
7#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, Default, IntoStaticStr)]
8#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9#[strum(serialize_all = "snake_case")]
10pub enum ClosedInterval {
11 #[default]
12 Both,
13 Left,
14 Right,
15 None,
16}
17
18pub fn new_linear_space_f32(
19 start: f32,
20 end: f32,
21 n: u64,
22 closed: ClosedInterval,
23 name: PlSmallStr,
24) -> PolarsResult<Float32Chunked> {
25 let mut ca = match n {
26 0 => Float32Chunked::full_null(name, 0),
27 1 => match closed {
28 ClosedInterval::None => Float32Chunked::from_slice(name, &[(end + start) * 0.5]),
29 ClosedInterval::Left | ClosedInterval::Both => {
30 Float32Chunked::from_slice(name, &[start])
31 },
32 ClosedInterval::Right => Float32Chunked::from_slice(name, &[end]),
33 },
34 _ => Float32Chunked::from_iter_values(name, {
35 let span = end - start;
36
37 let (start, d, end) = match closed {
38 ClosedInterval::None => {
39 let d = span / (n + 1) as f32;
40 (start + d, d, end - d)
41 },
42 ClosedInterval::Left => (start, span / n as f32, end - span / n as f32),
43 ClosedInterval::Right => (start + span / n as f32, span / n as f32, end),
44 ClosedInterval::Both => (start, span / (n - 1) as f32, end),
45 };
46 (0..n - 1)
47 .map(move |v| (v as f32 * d) + start)
48 .chain(std::iter::once(end)) }),
50 };
51
52 let is_sorted = if end < start {
53 IsSorted::Descending
54 } else {
55 IsSorted::Ascending
56 };
57 ca.set_sorted_flag(is_sorted);
58 Ok(ca)
59}
60
61pub fn new_linear_space_f64(
62 start: f64,
63 end: f64,
64 n: u64,
65 closed: ClosedInterval,
66 name: PlSmallStr,
67) -> PolarsResult<Float64Chunked> {
68 let mut ca = match n {
69 0 => Float64Chunked::full_null(name, 0),
70 1 => match closed {
71 ClosedInterval::None => Float64Chunked::from_slice(name, &[(end + start) * 0.5]),
72 ClosedInterval::Left | ClosedInterval::Both => {
73 Float64Chunked::from_slice(name, &[start])
74 },
75 ClosedInterval::Right => Float64Chunked::from_slice(name, &[end]),
76 },
77 _ => Float64Chunked::from_iter_values(name, {
78 let span = end - start;
79
80 let (start, d, end) = match closed {
81 ClosedInterval::None => {
82 let d = span / (n + 1) as f64;
83 (start + d, d, end - d)
84 },
85 ClosedInterval::Left => (start, span / n as f64, end - span / n as f64),
86 ClosedInterval::Right => (start + span / n as f64, span / n as f64, end),
87 ClosedInterval::Both => (start, span / (n - 1) as f64, end),
88 };
89 (0..n - 1)
90 .map(move |v| (v as f64 * d) + start)
91 .chain(std::iter::once(end)) }),
93 };
94
95 let is_sorted = if end < start {
96 IsSorted::Descending
97 } else {
98 IsSorted::Ascending
99 };
100 ca.set_sorted_flag(is_sorted);
101 Ok(ca)
102}