SMath 1.5.0
dotnet add package SMath --version 1.5.0
NuGet\Install-Package SMath -Version 1.5.0
<PackageReference Include="SMath" Version="1.5.0" />
<PackageVersion Include="SMath" Version="1.5.0" />
<PackageReference Include="SMath" />
paket add SMath --version 1.5.0
#r "nuget: SMath, 1.5.0"
#:package SMath@1.5.0
#addin nuget:?package=SMath&version=1.5.0
#tool nuget:?package=SMath&version=1.5.0
<p align="center"> <img src="src/code/SMath/icon.png" alt="SMath" width="50"/> </p>
SMath
Geometry, statistics and combinatorics for .NET, written against
generic math.
Every formula is generic over the numeric type, so the same call site works for double,
float, decimal or Half without overloads or casting.
Documentation
Full API reference, guides, and performance benchmarks are available on the Documentation Website.
Design
Generic over the number type. Constraints express the mathematics rather than a concrete
type: a formula needing a square root asks for IRootFunctions<N>, one needing only addition
asks for INumberBase<N>. Passing a type that cannot support the operation is a compile error.
Static and allocation free. There are no wrapper structs for points or vectors. Coordinates
are plain tuples such as (N X, N Y), so values stay on the stack and interoperate with any
other library. All entry points are static.
Names that read as the formula. Types are nested by the quantity being computed and the
input it comes from, giving call sites like Circle.Region.Area.FromRadius(r) or
Line.Segment.Length.FromTwoPoints(a, b).
Functions describe themselves. A function of one variable reports its parity, continuity, domain, image
and plain text formula next to Eval and DerivativeEval, so a caller can reason about the function without
hard coding its properties.
Span overloads on the hot paths. Statistics and grid traversal accept ReadOnlySpan<T>
next to IEnumerable<T>, avoiding enumerator allocation and interface dispatch per element.
Coordinate generators additionally offer buffer filling overloads, so a caller can size a
buffer with the matching count helper and reuse or stackalloc it.
Installation
dotnet add package SMath
Contents
| Area | Types |
|---|---|
| Geometry 1D | LineSegment |
| Geometry 2D | Point2, Line (ray, segment, projection, intersection), Circle (arc, chord, sector, segment, tangents, distance, intersection), Ellipse, Hyperbola, Parabola, Polygon (shoelace area, centroid, containment), Triangle (equilateral, isosceles, right), Rectangle, Square, Rhombus, RegularHexagon, GeometricVector2 (polar/cartesian, normals, rotation, reflection, dot/cross product), Function1Geometry |
| Geometry 3D | Point3 (distances, neighbors, grid traversal), Sphere, SphereCap, BallCap, SphericalShell, Ellipsoid, Cuboid |
| Statistics | ArithmeticMean (also weighted), GeometricMean, HarmonicMean, QuadraticMean, CubicMean, GeneralizedMean, Median, Mode, Variance, StandardDeviation, Moment, Skewness, Kurtosis, Covariance, PearsonCorrelation (cross, auto, weighted), SpearmanRankCorrelation, KendallCorrelation, CramerCorrelation, Histogram |
| Combinatorics | Permutations, PermutationsWithRepetition, Combinations, CombinationsWithRepetition |
| Sequences | ArithmeticSequence, GeometricSequence, FibonacciSequence, GeneralisedFibonacciSequence, CollatzConjecture |
| Series | ArithmeticSeries, GeometricSeries |
| Expansions | BinomialCoefficient, PascalsTriangle |
| Functions (1D) | Identity, Sine, Cosine, Tangent, Cotangent, Power2 to Power8, Root2 to Root8, Reciprocal, Exponential, NaturalExponential, Logarithm, Polynomial, SigmoidFunction, BipolarSigmoid, LogisticFunction, GaussianFunction, SignFunction, StepFunction, UnitStepFunction |
| Functions (2D & nD) | AckleyFunction, BoothFunction, RastriginFunction, RosenbrockFunction |
| Distances (nD) | EuclideanDistance, ManhattanDistance, ChebyshevDistance, HammingDistance |
| General & Extensions | BinaryIntegerExtension (Hamming distance, Gray code, GCD, Pow), Factorial, Determinant, PythagorasTheorem, Summation |
Distance metrics available on Point2 and Point3: Euclidean, Manhattan, Chebyshev and
Minkowski, plus Canberra in 3D.
Both points also generate integer coordinates by metric: neighbors, the coordinates at an exact distance, up to a distance or within a distance range, optionally limited by bounds. In 2D these are the taxicab circle and disk and the Chebyshev ring and square, in 3D the taxicab sphere and ball, an octahedron, and the Chebyshev shell and cube.
Usage
Geometry, with the numeric type inferred from the arguments:
using SMath.Geometry2D;
// double and float from the same generic method
var tangentD = Circle.TangentLine.FromAngle(radius: 5d, angle: double.Pi / 4d);
var tangentF = Circle.TangentLine.FromAngle(radius: 5f, angle: float.Pi / 4f);
// tangent points from an external point, then the secant line through them
var points = Circle.TangentPoint.FromPoint(radius: 2d, (4, 4));
var secant = Line.FromTwoPoints(points.Value.Point1, points.Value.Point2);
var area = Circle.Region.Area.FromRadius(2d);
Statistics, over a sequence or a span:
using SMath.Statistics;
double[] values = [1, 2, 3, 4, 5];
var mean = ArithmeticMean.Eval(values);
var variance = Variance.Sample.Eval(values);
var deviation = StandardDeviation.Sample.Eval(values);
double[] other = [2, 1, 4, 3, 5];
var correlation = PearsonCorrelation.Eval<double>(values, other);
// pairs counted in proportion to their weight, the weights need not sum to one
double[] weights = [1, 1, 2, 3, 5];
var weightedCorrelation = PearsonCorrelation.Weighted.Eval<double>(values, other, weights);
Counting and enumerating, with the counts evaluated so that only the result has to fit into the number type:
using SMath.Combinatorics;
using SMath.Expansions;
var hands = Combinations.Count(52, 5); // 2598960
var wide = BinomialCoefficient.Eval(60L, 30L); // the factorial form would overflow a long
var draws = PermutationsWithRepetition.Count(6, 3);
foreach (var indices in Combinations.Tuples(5, 3))
{
// every 3 element combination of the indices 0 to 4, in lexicographic order
}
Sequences and their partial sums, over a sequence type of your choice:
using SMath.Sequences;
using SMath.Series;
var fibonacci = FibonacciSequence.Terms<long>(10);
var term = GeometricSequence.Term(initial: 8d, ratio: 0.5, n: 4);
var sum = GeometricSeries.Term(initial: 8d, ratio: 0.5, n: 4);
var limit = GeometricSeries.Limit(initial: 8d, ratio: 0.5);
Span<double> buffer = stackalloc double[16];
var count = ArithmeticSequence.Terms(initial: 1d, difference: 2d, count: 16, destination: buffer);
Grid traversal without allocating, using a count helper to size the buffer:
using SMath.Geometry2D;
var center = (X: 0, Y: 0);
const int radius = 3;
Span<(int X, int Y)> buffer = stackalloc (int X, int Y)[Point2.ManhattanDiskCount(radius)];
var count = Point2.CoordinatesUpToManhattanDistance(center, radius, buffer);
foreach (var coordinate in buffer[..count])
{
// visit each coordinate within the taxicab disk
}
The same in three dimensions, walking a solid octahedron of voxels:
using SMath.Geometry3D;
var origin = (X: 0, Y: 0, Z: 0);
Span<(int X, int Y, int Z)> voxels = stackalloc (int X, int Y, int Z)[Point3.ManhattanBallCount(radius)];
var voxelCount = Point3.CoordinatesUpToManhattanDistance(origin, radius, voxels);
// only the shell, or the 26 neighbors of a voxel
var shell = Point3.CoordinatesAtChebyshevDistance(origin, radius);
var neighbors = Point3.AxialNeighbors(origin)
.Concat(Point3.EdgeNeighbors(origin))
.Concat(Point3.DiagonalNeighbors(origin));
Cross correlation over a range of lags, writing into a caller owned buffer:
using SMath.Statistics;
int[] lags = [-2, -1, 0, 1, 2];
var coefficients = new double[lags.Length];
PearsonCorrelation.Cross.Eval<double, int>(values, other, lags, coefficients);
Contributing
Ideas, bug reports and pull requests are welcome. Open an issue to propose a change, or send a pull request directly.
License
Project is under MIT license.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net7.0
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on SMath:
| Package | Downloads |
|---|---|
|
SPhysics
Physics library based on .NET generic math. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.5.0 | 223 | 9/29/2026 |
| 1.4.0 | 288 | 8/18/2026 |
| 1.3.0 | 127 | 8/12/2026 |
| 1.2.0 | 396 | 8/5/2026 |
| 1.1.0 | 133 | 8/4/2026 |
| 1.0.0 | 166 | 8/3/2026 |
| 0.9.0 | 1,210 | 4/3/2025 |
| 0.8.0 | 797 | 3/3/2025 |
| 0.7.0 | 452 | 9/26/2023 |
| 0.6.0 | 339 | 8/22/2023 |
| 0.5.0 | 364 | 6/5/2023 |
| 0.4.0 | 372 | 6/4/2023 |
| 0.3.0 | 370 | 6/2/2023 |
| 0.2.0 | 371 | 6/1/2023 |
| 0.1.0 | 354 | 5/31/2023 |