|
| 1 | +//! Deterministic scalar arithmetic abstraction for Echo math. |
| 2 | +//! |
| 3 | +//! This trait provides a minimal, platform-stable surface for numeric code in |
| 4 | +//! Echo to depend on without committing to a single concrete representation. |
| 5 | +//! Implementations must uphold determinism across supported platforms and are |
| 6 | +//! expected to encapsulate representation-specific policies (e.g., float32 |
| 7 | +//! canonicalization or fixed-point scaling). |
| 8 | +//! |
| 9 | +//! Scope (Issue #115): |
| 10 | +//! - Core arithmetic: add, sub, mul, div, neg. |
| 11 | +//! - Core transcendentals: sin, cos (angles in radians). |
| 12 | +//! |
| 13 | +//! Out of scope for this commit: |
| 14 | +//! - Canonicalization of `-0.0` to `+0.0` and subnormal flushing (to be handled |
| 15 | +//! by concrete float wrappers in a follow-up task). |
| 16 | +//! - Lookup-table or polynomial-backed trig implementations (tracked separately; |
| 17 | +//! this trait only declares the API). |
| 18 | +//! - Concrete backends: `F32Scalar` and `DFix64` will implement this trait in |
| 19 | +//! subsequent changes. |
| 20 | +//! |
| 21 | +//! Determinism contract: |
| 22 | +//! - Operations must be pure and total for all valid inputs of the |
| 23 | +//! implementation’s domain. |
| 24 | +//! - For floating-point backends, implementations are responsible for any |
| 25 | +//! canonicalization/flush semantics required by Echo’s determinism policy. |
| 26 | +//! - Trigonometric functions interpret arguments as radians and must be |
| 27 | +//! consistent across platforms for identical inputs (e.g., via LUT/polynomial |
| 28 | +//! in later work). |
| 29 | +
|
| 30 | +use core::ops::{Add, Div, Mul, Neg, Sub}; |
| 31 | + |
| 32 | +/// Deterministic scalar arithmetic and basic transcendentals. |
| 33 | +/// |
| 34 | +/// This trait abstracts the numeric core used by Echo so that engine code can |
| 35 | +/// be written generically and later bound to either a deterministic float32 |
| 36 | +/// wrapper (`F32Scalar`) or a fixed-point implementation (`DFix64`). Arithmetic |
| 37 | +/// operators are required via the standard operator traits for ergonomic use of |
| 38 | +/// `+`, `-`, `*`, `/`, and unary `-` in generic code. |
| 39 | +pub trait Scalar: |
| 40 | + Copy |
| 41 | + + core::fmt::Debug |
| 42 | + + PartialEq |
| 43 | + + Send |
| 44 | + + Sync |
| 45 | + + 'static |
| 46 | + + Add<Output = Self> |
| 47 | + + Sub<Output = Self> |
| 48 | + + Mul<Output = Self> |
| 49 | + + Div<Output = Self> |
| 50 | + + Neg<Output = Self> |
| 51 | +{ |
| 52 | + /// Returns the additive identity (zero). |
| 53 | + fn zero() -> Self; |
| 54 | + |
| 55 | + /// Returns the multiplicative identity (one). |
| 56 | + fn one() -> Self; |
| 57 | + |
| 58 | + /// Returns the sine of `self` (radians) under deterministic semantics. |
| 59 | + fn sin(self) -> Self; |
| 60 | + |
| 61 | + /// Returns the cosine of `self` (radians) under deterministic semantics. |
| 62 | + fn cos(self) -> Self; |
| 63 | + |
| 64 | + /// Returns both sine and cosine of `self` (radians). |
| 65 | + /// |
| 66 | + /// Default implementation computes `sin` and `cos` separately; concrete |
| 67 | + /// implementations may override for efficiency or shared range reduction. |
| 68 | + fn sin_cos(self) -> (Self, Self) { |
| 69 | + (self.sin(), self.cos()) |
| 70 | + } |
| 71 | + |
| 72 | + /// Converts from `f32` into this scalar type. |
| 73 | + /// |
| 74 | + /// This is intended for boundary crossings (e.g., deserializing payloads) |
| 75 | + /// and test scaffolding. Implementations must apply any necessary |
| 76 | + /// canonicalization required by Echo’s determinism policy. |
| 77 | + fn from_f32(value: f32) -> Self; |
| 78 | + |
| 79 | + /// Converts this scalar value to `f32` for interop and diagnostics. |
| 80 | + /// |
| 81 | + /// Implementations should define rounding policy precisely (e.g., ties to |
| 82 | + /// even) and ensure platform-stable results. |
| 83 | + fn to_f32(self) -> f32; |
| 84 | +} |
0 commit comments