sphrs 0.2.0 released
Posted January 15, 2023 by Stefan Kroboth ‐ 4 min read
This post announces the release of version 0.2.0 of sphrs, a spherical harmonics and solid harmonics library for Rust.
Introduction to sphrs
The crate computes
- real and complex spherical harmonics
- real and complex regular solid harmonics
- real and complex irregular solid harmonics
using Cartesian and polar coordinates.
Here is a small example to illustrate the API which computes the real valued spherical harmonic of degree \(l=2\) and order \(m=1\) at Cartesian position \((x, y, z) = (1.0, 0.2, 1.4)\):
use sphrs::{Coordinates, RealSH, SHEval};
// l = 2
let degree = 2;
// m = 1
let order = 1;
// Define the position where the SH will be evaluated at
// in Cartesian coordinates
let p = Coordinates::cartesian(1.0, 0.2, 1.4);
// Compute the real-valued SH value at `p` for l = 2, m = 1
let computed_sh = RealSH::Spherical.eval(degree, order, &p);
println!("SH ({}, {}): {:?}", degree, order, computed_sh);
The library also provides the type HarmonicsSet
which computes all harmonics up to a given order and returns them in a Vec
:
use sphrs::{ComplexSH, Coordinates, HarmonicsSet};
// l = 3
let degree = 3;
// Create the harmonics set (in this case for complex SH)
let sh = HarmonicsSet::new(degree, ComplexSH::Spherical);
// Position in spherical coordinates where the set is evaluated at
let p = Coordinates::spherical(1.0, 0.8, 0.4);
// Evaluate. Returns a `Vec<f64>`
let set = sh.eval(&p);
println!("SH up to degree {}: {:?}", degree, set);
// The individual SHs can also be multiplied with coefficients
// Note: `coeff` must have the same length as the number of SH.
let coeff = vec![2.0; sh.num_sh()];
let set = sh.eval_with_coefficients(&p, coeff.as_slice());
println!("SH up to degree {}: {:?}", degree, set);
More details on how to use sphrs can be found in the API documentation.
Harmonics up to third order are implemented according to their respective formulas in order to achieve good performance. For higher orders, a recursive implementation is used.
Version 0.2.0
The new version follows more than a year after the previous version 0.1.3 and comes with a couple of changes. Most of those changes concern the project structure and the CI; however some are user-facing and breaking changes:
- Updated dependencies
num
(v0.4),num-complex
(v0.4) andnum-traits
(v0.2) - Updated to Rust Edition 2021
- Improved documentation
- Every
SH
in function names was changed tosh
RealSHType
andComplexSHType
lost theirType
prefix and are now justRealSH
andComplexSH
- Functions which accepted
&dyn SHCoordinates
now accept&impl SHCoordinates
instead - The modules
coords
andsh
are notpub
anymore, all relevant types are re-exported at the crate root - Removed automatic conversion of inputs to the type of the output when creating
Coordinates
, since this required users to provide the desired output type as type hints:
// Version 0.1.3 (required a type hint)
// Still compiles in 0.2.0
let p: Coordinates<f64> = Coordinates::spherical(1.0, 0.8, 0.4);
// Version 0.2.0 (does not require a type hint)
// The `T` of `Coordinates<T>` will be equal to the type of the input arguments
let p = Coordinates::spherical(1.0, 0.8, 0.4);
- The generics of
HarmonicsSet
were also changed such that type hints are not necessary anymore. In fact, the type hints needed with 0.1.3 will break compilation with 0.2.0:
// Version 0.1.3 (required a type hint)
// This will *not* compile in 0.2.0
let sh: HarmonicsSet<f64, _, _> = HarmonicsSet::new(degree, RealSHType::Spherical);
// Version 0.2.0 (does not require a type hint)
let sh = HarmonicsSet::new(degree, RealSHType::Spherical);
Acknowledgements
The implementation is inspired by Google's spherical-harmonics library and follows the math outlined in this document.
Future steps
In the future this crate will hopefully see an increase in test coverage and potentially a Python wrapper. If you have any ideas for further development or if you even want to contribute, feel free to open an issue.