Leavitt Convolution Acceleration
length = 70 | norm_length = 150 | use_norm_hyperbolic = true Overview
Leavitt Convolution Acceleration produces two aligned outputs: a continuous convolution-acceleration value and a discrete signal state. The implementation projects the source through a rolling linear regression, measures the slope of that projection across a shorter square-root window, normalizes the slope with a rolling mean and standard deviation, and then derives acceleration from the change in the normalized value.
When hyperbolic normalization is enabled, the normalized slope is mapped with a hyperbolic transform and the
signal uses the raw acceleration slope. When it is disabled, the normalized slope is mapped with a logistic
transform and the signal instead uses the change in acceleration. Candle input defaults to the hlcc4
source, and the builder allows that candle source to be overridden.
Defaults: length = 70, norm_length = 150, use_norm_hyperbolic = true, candle source "hlcc4".
Implementation Examples
Calculate the acceleration and signal series from a slice or from candles:
use vector_ta::indicators::leavitt_convolution_acceleration::{
leavitt_convolution_acceleration, LeavittConvolutionAccelerationInput,
LeavittConvolutionAccelerationParams,
};
use vector_ta::utilities::data_loader::{Candles, read_candles_from_csv};
let data = vec![100.0, 101.2, 102.4, 101.9, 103.5, 104.1, 103.8, 105.0];
let input = LeavittConvolutionAccelerationInput::from_slice(
&data,
LeavittConvolutionAccelerationParams {
length: Some(70),
norm_length: Some(150),
use_norm_hyperbolic: Some(true),
},
);
let out = leavitt_convolution_acceleration(&input)?;
println!("{:?}", out.conv_acceleration);
println!("{:?}", out.signal);
// Default candles helper uses source = "hlcc4"
let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let out = leavitt_convolution_acceleration(
&LeavittConvolutionAccelerationInput::with_default_candles(&candles),
)?; API Reference
Input Methods ▼
LeavittConvolutionAccelerationInput::from_candles(&Candles, &str, LeavittConvolutionAccelerationParams) -> LeavittConvolutionAccelerationInput
LeavittConvolutionAccelerationInput::from_slice(&[f64], LeavittConvolutionAccelerationParams) -> LeavittConvolutionAccelerationInput
LeavittConvolutionAccelerationInput::with_default_candles(&Candles) -> LeavittConvolutionAccelerationInput // source = "hlcc4" Parameters Structure ▼
pub struct LeavittConvolutionAccelerationParams {
pub length: Option<usize>,
pub norm_length: Option<usize>,
pub use_norm_hyperbolic: Option<bool>,
}
// Defaults
// length = 70
// norm_length = 150
// use_norm_hyperbolic = true Output Structure ▼
pub struct LeavittConvolutionAccelerationOutput {
pub conv_acceleration: Vec<f64>,
pub signal: Vec<f64>,
}
// signal values:
// 2.0 = positive acceleration strengthening
// 1.0 = positive acceleration present
// 0.0 = neutral
// -1.0 = negative acceleration present
// -2.0 = negative acceleration strengthening Builders, Batch Range, and Stream ▼
LeavittConvolutionAccelerationBuilder::new()exposeslength(),norm_length(),use_norm_hyperbolic(),source(),kernel(),apply(),apply_slice(), andinto_stream().LeavittConvolutionAccelerationStream::update(value)returnsOption<(f64, f64)>for(conv_acceleration, signal).reset()clears all rolling states and source-history state.LeavittConvolutionAccelerationBatchRangecontainslength,norm_length, and optionaluse_norm_hyperbolic.LeavittConvolutionAccelerationBatchBuilder::new()exposeslength_range(),length_static(),norm_length_range(),norm_length_static(),use_norm_hyperbolic(),kernel(),apply_slice(), andapply_candles().- Batch output is
LeavittConvolutionAccelerationBatchOutputwith flattened row-majorconv_accelerationandsignalvectors pluscombos,rows, andcols.
Validation, Warmup & NaNs ▼
- Input must be non-empty and contain at least one finite source value; otherwise the indicator returns
EmptyInputDataorAllValuesNaN. lengthandnorm_lengthmust both be greater than zero and not exceed the input length.- Single-run validation requires at least
length + floor(sqrt(length)) + norm_length - 2finite values from the first valid source onward. - Single-output warmup fills values before
first_valid + length + floor(sqrt(length)) + norm_length - 3withNaN. - Streaming resets to empty state on non-finite input and returns
Noneuntil all rolling stages are ready again. - When
use_norm_hyperbolic = false, normalization uses a logistic transform and the signal slope is the change in acceleration instead of the raw acceleration slope.
Error Handling ▼
use vector_ta::indicators::leavitt_convolution_acceleration::LeavittConvolutionAccelerationError;
match leavitt_convolution_acceleration(&input) {
Ok(out) => {
println!("{:?}", out.conv_acceleration);
println!("{:?}", out.signal);
}
Err(LeavittConvolutionAccelerationError::EmptyInputData) =>
eprintln!("input data cannot be empty"),
Err(LeavittConvolutionAccelerationError::AllValuesNaN) =>
eprintln!("all source values were invalid"),
Err(LeavittConvolutionAccelerationError::InvalidLength { length, data_len }) =>
eprintln!("invalid length {} for data len {}", length, data_len),
Err(LeavittConvolutionAccelerationError::InvalidNormLength { norm_length, data_len }) =>
eprintln!("invalid norm_length {} for data len {}", norm_length, data_len),
Err(LeavittConvolutionAccelerationError::NotEnoughValidData { needed, valid }) =>
eprintln!("need {} valid points, only {} available", needed, valid),
Err(LeavittConvolutionAccelerationError::InvalidKernelForBatch(kernel)) =>
eprintln!("invalid batch kernel: {:?}", kernel),
Err(e) => eprintln!("Leavitt Convolution Acceleration error: {}", e),
} Python Bindings
Basic Usage ▼
Python exposes leavitt_convolution_acceleration(data, length=70, norm_length=150, use_norm_hyperbolic=True, kernel=None) and returns a tuple of NumPy arrays.
import numpy as np
from vector_ta import leavitt_convolution_acceleration
data = np.array([100.0, 101.2, 102.4, 101.9, 103.5, 104.1], dtype=np.float64)
conv_acceleration, signal = leavitt_convolution_acceleration(
data,
length=70,
norm_length=150,
use_norm_hyperbolic=True,
) Streaming Real-time Updates ▼
The Python stream class is LeavittConvolutionAccelerationStream. Its update(value) method returns either (conv_acceleration, signal) or None.
from vector_ta import LeavittConvolutionAccelerationStream
stream = LeavittConvolutionAccelerationStream(
length=70,
norm_length=150,
use_norm_hyperbolic=True,
)
for value in feed:
out = stream.update(value)
if out is not None:
conv_acceleration, signal = out
print(conv_acceleration, signal) Batch Processing ▼
leavitt_convolution_acceleration_batch returns a dict with both 2D outputs and grid metadata.
import numpy as np
from vector_ta import leavitt_convolution_acceleration_batch
result = leavitt_convolution_acceleration_batch(
data,
length_range=(50, 70, 20),
norm_length_range=(100, 150, 50),
use_norm_hyperbolic=True,
)
conv_acceleration = result["conv_acceleration"]
signal = result["signal"]
rows = result["rows"]
cols = result["cols"]
lengths = result["lengths"]
norm_lengths = result["norm_lengths"]
use_norm_hyperbolic = result["use_norm_hyperbolic"] JavaScript/WASM Bindings
Basic Usage ▼
WASM exports leavitt_convolution_acceleration_js(data, length, norm_length, use_norm_hyperbolic) and returns an object with both output arrays.
import { leavitt_convolution_acceleration_js } from 'vectorta-wasm';
const data = new Float64Array([100.0, 101.2, 102.4, 101.9, 103.5, 104.1]);
const out = leavitt_convolution_acceleration_js(data, 70, 150, true);
console.log(out.conv_acceleration);
console.log(out.signal); Memory-Efficient Operations ▼
Use leavitt_convolution_acceleration_alloc together with ..._into or ..._into_host to write both outputs into a caller-managed buffer of length len * 2.
import {
leavitt_convolution_acceleration_alloc,
leavitt_convolution_acceleration_free,
leavitt_convolution_acceleration_into_host,
memory,
} from 'vectorta-wasm';
const len = data.length;
const outPtr = leavitt_convolution_acceleration_alloc(len);
leavitt_convolution_acceleration_into_host(data, outPtr, 70, 150, true);
const flat = new Float64Array(memory.buffer, outPtr, len * 2);
const convAcceleration = flat.slice(0, len);
const signal = flat.slice(len, len * 2);
leavitt_convolution_acceleration_free(outPtr, len); Batch Processing ▼
WASM batch uses leavitt_convolution_acceleration_batch_js with length and normalization ranges and returns both row-major outputs plus combo metadata.
import { leavitt_convolution_acceleration_batch_js } from 'vectorta-wasm';
const batch = leavitt_convolution_acceleration_batch_js(data, {
length_range: [50, 70, 20],
norm_length_range: [100, 150, 50],
use_norm_hyperbolic: true,
});
console.log(batch.conv_acceleration);
console.log(batch.signal);
console.log(batch.rows, batch.cols);
console.log(batch.combos); CUDA Bindings (Rust)
Additional details for the CUDA bindings can be found inside the VectorTA repository.
Performance Analysis
Across sizes, Rust CPU runs about 1.14× faster than Tulip C in this benchmark.
AMD Ryzen 9 9950X (CPU) | NVIDIA RTX 4090 (GPU)