Skip to content

Commit

Permalink
add interpolate_linear function
Browse files Browse the repository at this point in the history
  • Loading branch information
georgypv committed Jan 29, 2024
1 parent 041dc67 commit 7a6ff76
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 2 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "polars_coord_transforms"
version = "0.6.0"
version = "0.7.0"
edition = "2021"

[lib]
Expand Down
12 changes: 12 additions & 0 deletions polars_coord_transforms/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,18 @@ def rotate_map_coords(self, rotation: pl.Expr, scale: pl.Expr) -> pl.Expr:
is_elementwise=True,
args=[rotation, scale],
)

def interpolate_linear(self, other: pl.Expr, coef=0.5):
if coef < 0 or coef > 1:
raise ValueError("`coef` parameter must be between 0 and 1!")

return self._expr.register_plugin(
lib=lib,
symbol="interpolate_linear",
is_elementwise=True,
args=[other,],
kwargs={"coef": coef},
)

@pl.api.register_expr_namespace("distance")
class DistanceNameSpace:
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ classifiers = [
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
]
version = "0.6.0"
version = "0.7.0"
authors = [
{name="Georgy Popov"}
]
Expand Down
6 changes: 6 additions & 0 deletions src/coord_transforms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ pub fn rotate_map_coords_elementwise(map_coords: Vec<f64>, rotation: Vec<f64>, s
}


pub fn interpolate_linear_elementwise(coords: Vec<f64>, other: Vec<f64>, coef: f64) -> (f64, f64, f64) {
let interpolated = (Vector3::from_vec(coords) * coef) + (Vector3::from_vec(other) * (1.0 - coef));
(interpolated.x, interpolated.y, interpolated.z)
}


#[cfg(test)]
mod transform_tests {
use crate::coord_transforms::{map_to_ecef_elementwise, ecef_to_lla_elementwise};
Expand Down
66 changes: 66 additions & 0 deletions src/expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,72 @@ fn cellid_to_vertices(inputs: &[Series]) -> PolarsResult<Series> {


//TransfromNameSpace
#[derive(Deserialize)]
struct TransformInterpolateKwargs {
coef: f64
}

fn output_3d(_: &[Field]) -> PolarsResult<Field> {
let v: Vec<Field> = vec![
Field::new("x", DataType::Float64),
Field::new("y", DataType::Float64),
Field::new("z", DataType::Float64),
];
Ok(Field::new("coords", DataType::Struct(v)))
}

#[polars_expr(output_type_func=output_3d)]
fn interpolate_linear(inputs: &[Series], kwargs: TransformInterpolateKwargs) -> PolarsResult<Series> {

let ca = inputs[0].struct_()?;
let ca_other = inputs[1].struct_()?;


let (x_ser, y_ser, z_ser) = unpack_xyz(ca, false);
let (x_other_ser, y_other_ser, z_other_ser) = unpack_xyz(ca_other, false);

let mut x_cb: PrimitiveChunkedBuilder<Float64Type> =
PrimitiveChunkedBuilder::new("x", ca.len());
let mut y_cb: PrimitiveChunkedBuilder<Float64Type> =
PrimitiveChunkedBuilder::new("y", ca.len());
let mut z_cb: PrimitiveChunkedBuilder<Float64Type> =
PrimitiveChunkedBuilder::new("z", ca.len());

for (x_op, y_op, z_op, x_other_op, y_other_op, z_other_op) in izip!(
x_ser.f64()?.into_iter(),
y_ser.f64()?.into_iter(),
z_ser.f64()?.into_iter(),
x_other_ser.f64()?.into_iter(),
y_other_ser.f64()?.into_iter(),
z_other_ser.f64()?.into_iter()
) {
match (x_op, y_op, z_op, x_other_op, y_other_op, z_other_op) {
(Some(x), Some(y), Some(z), Some(x_other), Some(y_other), Some(z_other)) => {

let (x_interpolated, y_interpolated, z_interpolated) = interpolate_linear_elementwise(vec![x, y, z], vec![x_other, y_other, z_other], kwargs.coef);
x_cb.append_value(x_interpolated);
y_cb.append_value(y_interpolated);
z_cb.append_value(z_interpolated);
},
_ => {
x_cb.append_null();
y_cb.append_null();
z_cb.append_null();
}
}
}

let ser_x = x_cb.finish().into_series();
let ser_y = y_cb.finish().into_series();
let ser_z = z_cb.finish().into_series();

let out_chunked = StructChunked::new("coords", &[ser_x, ser_y, ser_z])?;
Ok(out_chunked.into_series())

}



fn ecef_output(_: &[Field]) -> PolarsResult<Field> {
let v: Vec<Field> = vec![
Field::new("x", DataType::Float64),
Expand Down

0 comments on commit 7a6ff76

Please sign in to comment.