NAME
nvec - Experimental SIMD accelerated numeric vectors
SYNOPSIS
use nvec;
# Construction
my $a = nvec::new([1, 2, 3, 4, 5, 6, 7, 8]);
my $b = nvec::zeros(1000);
my $c = nvec::ones(1000);
my $d = nvec::fill(1000, 3.14);
my $e = nvec::range(0, 100); # 0..99
my $f = nvec::linspace(0, 1, 100); # 100 points from 0 to 1
# Element access
my $val = $a->get(5);
$a->set(5, 42.0);
my $len = $a->len();
my $aref = $a->to_array();
# Arithmetic (returns new nvec)
my $sum = $a->add($b);
my $diff = $a->sub($b);
my $prod = $a->mul($b);
my $quot = $a->div($b);
my $scaled = $a->scale(2.5);
my $negated = $a->neg();
# Operator overloading (implemented in XS)
my $c = $a + $b; # Element-wise add
my $c = $a - $b; # Element-wise subtract
my $c = $a * $b; # Element-wise multiply
my $c = $a / $b; # Element-wise divide
my $c = $a + 5; # Add scalar
my $c = $a * 2.5; # Scale
$a += $b; # In-place add
$a *= 2; # In-place scale
print "$a\n"; # Stringify
# In-place operations (modify, return self)
$a->add_inplace($b);
$a->scale_inplace(2.5);
# Reductions (return scalar)
my $total = $a->sum();
my $avg = $a->mean();
my $min = $a->min();
my $max = $a->max();
my $dot = $a->dot($b);
my $norm = $a->norm();
# Linear algebra
my $unit = $a->normalize();
my $dist = $a->distance($b);
my $sim = $a->cosine_similarity($b);
DESCRIPTION
nvec provides SIMD accelerated numeric vector operations. It automatically uses ARM NEON, x86 AVX, or SSE2 instructions where available, falling back to optimized scalar C code on other platforms.
Performance
Typical speedups over Perl arrays:
50-200x for element-wise operations
100-400x for reductions (sum, dot product)
Memory-aligned storage for optimal SIMD performance
Portability
The module detects SIMD capabilities at compile time:
ARM NEON (Apple Silicon, ARM64)
x86 AVX/AVX2 (modern Intel/AMD)
x86 SSE2 (older Intel/AMD)
Scalar fallback (any platform)
OPERATOR OVERLOADING
The following operators are overloaded (implemented in XS for maximum performance):
+ Addition (nvec + nvec or nvec + scalar)
- Subtraction (nvec - nvec or nvec - scalar)
* Multiplication (nvec * nvec or nvec * scalar)
/ Division (nvec / nvec or nvec / scalar)
+= In-place addition
-= In-place subtraction
*= In-place multiplication
/= In-place division
neg Unary negation (-$v)
abs Absolute value
"" Stringification
== Equality comparison
!= Inequality comparison
bool Boolean context (true if len > 0)
CONSTRUCTORS
new
my $v = nvec::new(\@array);
my $v = nvec::new([1.5, 2.5, 3.5]);
Create a new nvec from an arrayref of numbers.
zeros
my $v = nvec::zeros($n);
Create a nvec of N zeros.
ones
my $v = nvec::ones($n);
Create a nvec of N ones.
fill
my $v = nvec::fill($n, $value);
Create a nvec of N copies of $value.
range
my $v = nvec::range($start, $end);
Create a nvec from $start to $end-1 (exclusive end).
linspace
my $v = nvec::linspace($start, $end, $n);
Create N evenly spaced values from $start to $end (inclusive).
random
my $v = nvec::random($n);
Create a nvec of N random values between 0 and 1.
ELEMENT ACCESS
get
my $val = $v->get($index);
Get element at index. Croaks on out-of-bounds.
set
$v->set($index, $value);
Set element at index. Croaks on out-of-bounds.
len
my $n = $v->len();
Return the number of elements.
to_array
my $aref = $v->to_array();
Convert nvec to Perl arrayref.
ARITHMETIC
All arithmetic methods return a new vec, leaving the original unchanged.
add, sub, mul, div
my $c = $a->add($b); # $c[i] = $a[i] + $b[i]
my $c = $a->sub($b); # $c[i] = $a[i] - $b[i]
my $c = $a->mul($b); # $c[i] = $a[i] * $b[i]
my $c = $a->div($b); # $c[i] = $a[i] / $b[i]
Element-wise operations. Vectors must have same length.
scale
my $c = $a->scale($scalar);
Multiply all elements by a scalar.
add_scalar
my $c = $a->add_scalar($scalar);
Add a scalar to all elements.
neg
my $c = $a->neg();
Negate all elements.
abs
my $c = $a->abs();
Absolute value of all elements.
sqrt
my $c = $a->sqrt();
Square root of all elements.
pow
my $c = $a->pow($exponent);
Raise all elements to the given power.
TRIGONOMETRIC FUNCTIONS
sin, cos, tan
my $c = $a->sin();
my $c = $a->cos();
my $c = $a->tan();
Element-wise trigonometric functions (radians).
asin, acos, atan
my $c = $a->asin();
my $c = $a->acos();
my $c = $a->atan();
Element-wise inverse trigonometric functions.
HYPERBOLIC FUNCTIONS
sinh, cosh, tanh
my $c = $a->sinh();
my $c = $a->cosh();
my $c = $a->tanh();
Element-wise hyperbolic functions.
EXPONENTIAL AND LOGARITHMIC
exp
my $c = $a->exp();
Element-wise exponential (e^x).
log
my $c = $a->log();
Element-wise natural logarithm.
log10
my $c = $a->log10();
Element-wise base-10 logarithm.
log2
my $c = $a->log2();
Element-wise base-2 logarithm.
ROUNDING
floor
my $c = $a->floor();
Round down to nearest integer.
ceil
my $c = $a->ceil();
Round up to nearest integer.
round
my $c = $a->round();
Round to nearest integer.
sign
my $c = $a->sign();
Sign of each element (-1, 0, or 1).
clip
my $c = $a->clip($min, $max);
Clip values to range (returns new nvec).
IN-PLACE OPERATIONS
These modify the nvec and return self for chaining.
add_inplace, sub_inplace, mul_inplace, div_inplace
$a->add_inplace($b);
$a->sub_inplace($b);
$a->mul_inplace($b);
$a->div_inplace($b);
Element-wise in-place operations.
scale_inplace
$a->scale_inplace(2.5);
Scale all elements in-place.
clamp_inplace
$a->clamp_inplace($min, $max);
Clamp all values to range.
fma_inplace
$c->fma_inplace($a, $b); # c = a*b + c
Fused multiply-add. Uses hardware FMA when available.
axpy
$y->axpy($a, $x); # y = a*x + y
BLAS-style operation. Uses SIMD FMA for maximum performance.
SLICING AND COPY
slice
my $s = $v->slice($start, $len);
Extract a sub-vector. Negative start counts from end.
copy
my $c = $v->copy();
Create a deep copy of the vector.
concat
my $c = $a->concat($b);
Concatenate two vectors into a new vector.
reverse
my $c = $v->reverse();
Return a new vector with elements in reverse order.
fill_range
$v->fill_range($start, $len, $value);
Fill a range of elements with a value (in-place).
REDUCTIONS
sum
my $total = $v->sum();
Sum of all elements.
product
my $prod = $v->product();
Product of all elements.
mean
my $avg = $v->mean();
Average of all elements.
variance
my $var = $v->variance();
Sample variance (Bessel-corrected, divides by n-1).
std
my $s = $v->std();
Sample standard deviation.
min, max
my $min = $v->min();
my $max = $v->max();
Minimum/maximum element (SIMD-accelerated).
argmin, argmax
my $idx = $v->argmin();
my $idx = $v->argmax();
Index of minimum/maximum element.
dot
my $dp = $a->dot($b);
Dot product (inner product) of two vectors.
norm
my $len = $v->norm();
L2 norm (Euclidean length).
median
my $med = $v->median();
Median value of the vector.
CUMULATIVE OPERATIONS
cumsum
my $c = $v->cumsum();
Cumulative sum: c[i] = sum(v[0..i]).
cumprod
my $c = $v->cumprod();
Cumulative product: c[i] = product(v[0..i]).
diff
my $c = $v->diff();
First difference: c[i] = v[i+1] - v[i]. Result has len-1 elements.
SORTING
sort
my $c = $v->sort();
Return a new vector with elements sorted in ascending order.
argsort
my $c = $v->argsort();
Return indices that would sort the vector.
BOOLEAN REDUCTIONS
all
my $bool = $v->all();
True if all elements are non-zero.
any
my $bool = $v->any();
True if any element is non-zero.
count
my $n = $v->count();
Count of non-zero elements.
COMPARISON OPERATIONS
These return a new nvec with 1.0 where condition is true, 0.0 otherwise.
eq, ne
my $c = $a->eq($b); # $c[i] = ($a[i] == $b[i]) ? 1 : 0
my $c = $a->ne($b); # $c[i] = ($a[i] != $b[i]) ? 1 : 0
Element-wise equality/inequality comparison.
lt, le, gt, ge
my $c = $a->lt($b); # $c[i] = ($a[i] < $b[i]) ? 1 : 0
my $c = $a->le($b); # $c[i] = ($a[i] <= $b[i]) ? 1 : 0
my $c = $a->gt($b); # $c[i] = ($a[i] > $b[i]) ? 1 : 0
my $c = $a->ge($b); # $c[i] = ($a[i] >= $b[i]) ? 1 : 0
Element-wise relational comparisons.
where
my $c = $v->where($mask);
Select elements where mask is non-zero.
SPECIAL VALUE CHECKS
isnan
my $c = $v->isnan();
Return 1.0 where element is NaN, 0.0 otherwise.
isinf
my $c = $v->isinf();
Return 1.0 where element is infinite, 0.0 otherwise.
isfinite
my $c = $v->isfinite();
Return 1.0 where element is finite, 0.0 otherwise.
LINEAR ALGEBRA
normalize
my $unit = $v->normalize();
Return unit vector (same direction, norm = 1).
distance
my $d = $a->distance($b);
Euclidean distance between two vectors.
cosine_similarity
my $sim = $a->cosine_similarity($b);
Cosine similarity (-1 to 1).
UTILITIES
simd_info
my $info = nvec::simd_info();
Return a string describing the SIMD backend in use (e.g., "NEON", "AVX2", "SSE2", "scalar").
C API FOR XS MODULES
For XS modules that need direct access to nvec's SIMD operations, include nvec_api.h:
#include "nvec_api.h"
Object Lifecycle
Vec* vec_xs_create(pTHX_ IV capacity); // Create with capacity
void vec_xs_destroy(pTHX_ Vec *v); // Destroy (if not wrapping)
Vec* vec_xs_from_sv(pTHX_ SV *sv); // Extract from Perl SV
SV* vec_xs_wrap(pTHX_ Vec *v); // Wrap as Perl object
Data Access
double* vec_xs_data(Vec *v); // Get raw buffer pointer
IV vec_xs_len(Vec *v); // Get length
SIMD Operations
void vec_xs_add_impl(double *c, const double *a, const double *b, IV n);
void vec_xs_sub_impl(double *c, const double *a, const double *b, IV n);
void vec_xs_mul_impl(double *c, const double *a, const double *b, IV n);
void vec_xs_div_impl(double *c, const double *a, const double *b, IV n);
void vec_xs_scale_impl(double *c, const double *a, double s, IV n);
void vec_xs_add_inplace_impl(double *a, const double *b, IV n);
void vec_xs_scale_inplace_impl(double *a, double s, IV n);
double vec_xs_sum_impl(const double *a, IV n);
double vec_xs_dot_impl(const double *a, const double *b, IV n);
const char* vec_xs_simd_name(void);
Example (see t/xs/nvec_api_test/ for full working code):
Vec *v = vec_xs_create(aTHX_ 1000);
double *data = vec_xs_data(v);
for (IV i = 0; i < 1000; i++) data[i] = i * 0.5;
v->len = 1000;
double sum = vec_xs_sum_impl(data, 1000);
SV *sv = vec_xs_wrap(aTHX_ v); // Ownership transfers to Perl
AUTHOR
LNATION <email@lnation.org>
LICENSE
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.