diff --git a/src/BaseQuantities.zig b/src/Base.zig similarity index 54% rename from src/BaseQuantities.zig rename to src/Base.zig index 4eddaf8..df84713 100644 --- a/src/BaseQuantities.zig +++ b/src/Base.zig @@ -3,24 +3,24 @@ const std = @import("std"); // Adjust these imports to match your actual file names const Dimensions = @import("Dimensions.zig"); const Scales = @import("Scales.zig"); -const Quantity = @import("Quantity.zig").Quantity; +const Scalar = @import("Scalar.zig").Scalar; /// Helper function to create a clean namespace for each physical dimension. /// It exposes the raw dimensions, and easy type-creators for Base or Scaled variants. -pub fn QtyNamespace(comptime d: anytype) type { +pub fn BaseScalar(comptime d: anytype) type { return struct { pub const dims = Dimensions.init(d); - /// Creates a Quantity of this dimension using default scales. + /// Creates a Scalar of this dimension using default scales. /// Example: const V = Quantities.Velocity.Base(f32); pub fn Of(comptime T: type) type { - return Quantity(T, dims, Scales.init(.{})); + return Scalar(T, dims, Scales.init(.{})); } - /// Creates a Quantity of this dimension using custom scales. + /// Creates a Scalar of this dimension using custom scales. /// Example: const Kmh = Quantities.Velocity.Scaled(f32, Scales.init(.{ .L = .k, .T = .hour })); pub fn Scaled(comptime T: type, comptime s: Scales) type { - return Quantity(T, dims, s); + return Scalar(T, dims, s); } }; } @@ -28,70 +28,70 @@ pub fn QtyNamespace(comptime d: anytype) type { // ========================================== // Base Quantities // ========================================== -pub const Meter = QtyNamespace(.{ .L = 1 }); -pub const Second = QtyNamespace(.{ .T = 1 }); -pub const Gramm = QtyNamespace(.{ .M = 1 }); -pub const Kelvin = QtyNamespace(.{ .Tr = 1 }); -pub const ElectricCurrent = QtyNamespace(.{ .I = 1 }); +pub const Meter = BaseScalar(.{ .L = 1 }); +pub const Second = BaseScalar(.{ .T = 1 }); +pub const Gramm = BaseScalar(.{ .M = 1 }); +pub const Kelvin = BaseScalar(.{ .Tr = 1 }); +pub const ElectricCurrent = BaseScalar(.{ .I = 1 }); // ========================================== // Electric // ========================================== -pub const ElectricConductivity = QtyNamespace(.{ .M = -1, .L = -3, .T = 3, .I = 2 }); -pub const ElectricCharge = QtyNamespace(.{ .T = 1, .I = 1 }); -pub const ElectricPotential = QtyNamespace(.{ .T = -3, .L = 2, .M = 1, .I = -1 }); -pub const ElectricResistance = QtyNamespace(.{ .M = 1, .L = 2, .T = -3, .I = -2 }); -pub const ElectricResistivity = QtyNamespace(.{ .M = 1, .L = 3, .T = -3, .I = -2 }); -pub const ElectricCapacitance = QtyNamespace(.{ .T = 4, .L = -2, .M = -1, .I = 2 }); +pub const ElectricConductivity = BaseScalar(.{ .M = -1, .L = -3, .T = 3, .I = 2 }); +pub const ElectricCharge = BaseScalar(.{ .T = 1, .I = 1 }); +pub const ElectricPotential = BaseScalar(.{ .T = -3, .L = 2, .M = 1, .I = -1 }); +pub const ElectricResistance = BaseScalar(.{ .M = 1, .L = 2, .T = -3, .I = -2 }); +pub const ElectricResistivity = BaseScalar(.{ .M = 1, .L = 3, .T = -3, .I = -2 }); +pub const ElectricCapacitance = BaseScalar(.{ .T = 4, .L = -2, .M = -1, .I = 2 }); pub const ElectricImpedance = ElectricResistance; -pub const MagneticFlux = QtyNamespace(.{ .M = 1, .L = 2, .T = -2, .I = -1 }); -pub const MagneticDensity = QtyNamespace(.{ .M = 1, .T = -2, .I = -1 }); -pub const MagneticStrength = QtyNamespace(.{ .L = -1, .I = 1 }); // Fixed typo from MagneticStrengh -pub const MagneticMoment = QtyNamespace(.{ .L = 2, .I = 1 }); +pub const MagneticFlux = BaseScalar(.{ .M = 1, .L = 2, .T = -2, .I = -1 }); +pub const MagneticDensity = BaseScalar(.{ .M = 1, .T = -2, .I = -1 }); +pub const MagneticStrength = BaseScalar(.{ .L = -1, .I = 1 }); // Fixed typo from MagneticStrengh +pub const MagneticMoment = BaseScalar(.{ .L = 2, .I = 1 }); // ========================================== // Movement // ========================================== -pub const Velocity = QtyNamespace(.{ .L = 1, .T = -1 }); -pub const Acceleration = QtyNamespace(.{ .L = 1, .T = -2 }); -pub const Inertia = QtyNamespace(.{ .M = 1, .L = 2 }); +pub const Speed = BaseScalar(.{ .L = 1, .T = -1 }); +pub const Acceleration = BaseScalar(.{ .L = 1, .T = -2 }); +pub const Inertia = BaseScalar(.{ .M = 1, .L = 2 }); // ========================================== // Forces / Energy // ========================================== -pub const Force = QtyNamespace(.{ .T = -2, .M = 1, .L = 1 }); -pub const Pressure = QtyNamespace(.{ .T = -2, .L = -1, .M = 1 }); -pub const Energy = QtyNamespace(.{ .T = -2, .L = 2, .M = 1 }); -pub const Power = QtyNamespace(.{ .T = -3, .L = 2, .M = 1 }); +pub const Force = BaseScalar(.{ .T = -2, .M = 1, .L = 1 }); +pub const Pressure = BaseScalar(.{ .T = -2, .L = -1, .M = 1 }); +pub const Energy = BaseScalar(.{ .T = -2, .L = 2, .M = 1 }); +pub const Power = BaseScalar(.{ .T = -3, .L = 2, .M = 1 }); // ========================================== // Dimension // ========================================== -pub const Area = QtyNamespace(.{ .L = 2 }); -pub const Volume = QtyNamespace(.{ .L = 3 }); -pub const AreaDensity = QtyNamespace(.{ .M = 1, .L = -2 }); -pub const Density = QtyNamespace(.{ .M = 1, .L = -3 }); +pub const Area = BaseScalar(.{ .L = 2 }); +pub const Volume = BaseScalar(.{ .L = 3 }); +pub const AreaDensity = BaseScalar(.{ .M = 1, .L = -2 }); +pub const Density = BaseScalar(.{ .M = 1, .L = -3 }); // ========================================== // Thermal // ========================================== pub const ThermalHeat = Energy; pub const ThermalWork = Energy; -pub const ThermalCapacity = QtyNamespace(.{ .M = 1, .L = 2, .T = -2, .Tr = -1 }); -pub const ThermalCapacityPerMass = QtyNamespace(.{ .L = 2, .T = -2, .Tr = -1 }); -pub const ThermalFluxDensity = QtyNamespace(.{ .M = 1, .T = -3 }); // Fixed typo from ThermalluxDensity -pub const ThermalConductance = QtyNamespace(.{ .M = 1, .L = 2, .T = -3, .Tr = -1 }); -pub const ThermalConductivity = QtyNamespace(.{ .M = 1, .L = 1, .T = -3, .Tr = -1 }); -pub const ThermalResistance = QtyNamespace(.{ .M = -1, .L = -2, .T = 3, .Tr = 1 }); -pub const ThermalResistivity = QtyNamespace(.{ .M = -1, .L = -1, .T = 3, .Tr = 1 }); -pub const ThermalEntropy = QtyNamespace(.{ .M = 1, .L = 2, .T = -2, .Tr = -1 }); +pub const ThermalCapacity = BaseScalar(.{ .M = 1, .L = 2, .T = -2, .Tr = -1 }); +pub const ThermalCapacityPerMass = BaseScalar(.{ .L = 2, .T = -2, .Tr = -1 }); +pub const ThermalFluxDensity = BaseScalar(.{ .M = 1, .T = -3 }); // Fixed typo from ThermalluxDensity +pub const ThermalConductance = BaseScalar(.{ .M = 1, .L = 2, .T = -3, .Tr = -1 }); +pub const ThermalConductivity = BaseScalar(.{ .M = 1, .L = 1, .T = -3, .Tr = -1 }); +pub const ThermalResistance = BaseScalar(.{ .M = -1, .L = -2, .T = 3, .Tr = 1 }); +pub const ThermalResistivity = BaseScalar(.{ .M = -1, .L = -1, .T = 3, .Tr = 1 }); +pub const ThermalEntropy = BaseScalar(.{ .M = 1, .L = 2, .T = -2, .Tr = -1 }); // ========================================== // Others // ========================================== -pub const Frequency = QtyNamespace(.{ .T = -1 }); -pub const Viscosity = QtyNamespace(.{ .M = 1, .L = -1, .T = -1 }); -pub const SurfaceTension = QtyNamespace(.{ .M = 1, .T = -2 }); // Corrected from MT-2a +pub const Frequency = BaseScalar(.{ .T = -1 }); +pub const Viscosity = BaseScalar(.{ .M = 1, .L = -1, .T = -1 }); +pub const SurfaceTension = BaseScalar(.{ .M = 1, .T = -2 }); // Corrected from MT-2a test "BaseQuantities - Core dimensions instantiation" { // Basic types via generic wrappers @@ -102,7 +102,7 @@ test "BaseQuantities - Core dimensions instantiation" { try std.testing.expectEqual(0, M.dims.get(.T)); // Test specific scale variants - const Kmh = Velocity.Scaled(f32, Scales.init(.{ .L = .k, .T = .hour })); + const Kmh = Speed.Scaled(f32, Scales.init(.{ .L = .k, .T = .hour })); const speed = Kmh{ .value = 120.0 }; try std.testing.expectEqual(120.0, speed.value); try std.testing.expectEqual(.k, @TypeOf(speed).scales.get(.L)); @@ -116,7 +116,7 @@ test "BaseQuantities - Kinematics equations" { // Velocity = Distance / Time const v = d.divBy(t); try std.testing.expectEqual(25.0, v.value); - try std.testing.expect(Velocity.dims.eql(@TypeOf(v).dims)); + try std.testing.expect(Speed.dims.eql(@TypeOf(v).dims)); // Acceleration = Velocity / Time const a = v.divBy(t); diff --git a/src/Quantity.zig b/src/Scalar.zig similarity index 87% rename from src/Quantity.zig rename to src/Scalar.zig index 96c138c..373fd25 100644 --- a/src/Quantity.zig +++ b/src/Scalar.zig @@ -1,25 +1,25 @@ const std = @import("std"); const hlp = @import("helper.zig"); -const QuantityVec = @import("QuantityVec.zig").QuantityVec; +const Vector = @import("Vector.zig").Vector; const Scales = @import("Scales.zig"); const UnitScale = Scales.UnitScale; const Dimensions = @import("Dimensions.zig"); const Dimension = Dimensions.Dimension; -pub fn Quantity(comptime T: type, comptime d: Dimensions, comptime s: Scales) type { +pub fn Scalar(comptime T: type, comptime d: Dimensions, comptime s: Scales) type { @setEvalBranchQuota(100_000); return struct { value: T, const Self = @This(); - pub const Vec3: type = QuantityVec(3, Self); + pub const Vec3: type = Vector(3, Self); pub const ValueType: type = T; pub const dims: Dimensions = d; pub const scales = s; - pub inline fn add(self: Self, rhs: anytype) Quantity( + pub inline fn add(self: Self, rhs: anytype) Scalar( T, dims, scales.min(@TypeOf(rhs).scales), @@ -29,14 +29,14 @@ pub fn Quantity(comptime T: type, comptime d: Dimensions, comptime s: Scales) ty if (comptime @TypeOf(rhs) == Self) return .{ .value = self.value + rhs.value }; - const TargetType = Quantity(T, dims, scales.min(@TypeOf(rhs).scales)); + const TargetType = Scalar(T, dims, scales.min(@TypeOf(rhs).scales)); const lhs_val = if (comptime @TypeOf(self) == TargetType) self.value else self.to(TargetType).value; const rhs_val = if (comptime @TypeOf(rhs) == TargetType) rhs.value else rhs.to(TargetType).value; return .{ .value = lhs_val + rhs_val }; } - pub inline fn sub(self: Self, rhs: anytype) Quantity( + pub inline fn sub(self: Self, rhs: anytype) Scalar( T, dims, scales.min(@TypeOf(rhs).scales), @@ -46,21 +46,21 @@ pub fn Quantity(comptime T: type, comptime d: Dimensions, comptime s: Scales) ty if (comptime @TypeOf(rhs) == Self) return .{ .value = self.value - rhs.value }; - const TargetType = Quantity(T, dims, scales.min(@TypeOf(rhs).scales)); + const TargetType = Scalar(T, dims, scales.min(@TypeOf(rhs).scales)); const lhs_val = if (comptime @TypeOf(self) == TargetType) self.value else self.to(TargetType).value; const rhs_val = if (comptime @TypeOf(rhs) == TargetType) rhs.value else rhs.to(TargetType).value; return .{ .value = lhs_val - rhs_val }; } - pub inline fn mulBy(self: Self, rhs: anytype) Quantity( + pub inline fn mulBy(self: Self, rhs: anytype) Scalar( T, dims.add(@TypeOf(rhs).dims), scales.min(@TypeOf(rhs).scales), ) { const RhsType = @TypeOf(rhs); - const SelfNorm = Quantity(T, dims, scales.min(RhsType.scales)); - const RhsNorm = Quantity(T, RhsType.dims, scales.min(RhsType.scales)); + const SelfNorm = Scalar(T, dims, scales.min(RhsType.scales)); + const RhsNorm = Scalar(T, RhsType.dims, scales.min(RhsType.scales)); if (comptime Self == SelfNorm and RhsType == RhsNorm) return .{ .value = self.value * rhs.value }; @@ -69,14 +69,14 @@ pub fn Quantity(comptime T: type, comptime d: Dimensions, comptime s: Scales) ty return .{ .value = lhs_val * rhs_val }; } - pub inline fn divBy(self: Self, rhs: anytype) Quantity( + pub inline fn divBy(self: Self, rhs: anytype) Scalar( T, dims.sub(@TypeOf(rhs).dims), scales.min(@TypeOf(rhs).scales), ) { const RhsType = @TypeOf(rhs); - const SelfNorm = Quantity(T, dims, scales.min(RhsType.scales)); - const RhsNorm = Quantity(T, RhsType.dims, scales.min(RhsType.scales)); + const SelfNorm = Scalar(T, dims, scales.min(RhsType.scales)); + const RhsNorm = Scalar(T, RhsType.dims, scales.min(RhsType.scales)); const lhs_val = if (comptime Self == SelfNorm) self.value else self.to(SelfNorm).value; const rhs_val = if (comptime RhsType == RhsNorm) rhs.value else rhs.to(RhsNorm).value; if (comptime @typeInfo(T) == .int) { @@ -132,8 +132,8 @@ pub fn Quantity(comptime T: type, comptime d: Dimensions, comptime s: Scales) ty } } - pub fn Vec(self: Self, comptime len: comptime_int) QuantityVec(len, Self) { - return QuantityVec(len, Self).initDefault(self.value); + pub fn Vec(self: Self, comptime len: comptime_int) Vector(len, Self) { + return Vector(len, Self).initDefault(self.value); } pub fn vec3(self: Self) Vec3 { @@ -168,8 +168,8 @@ pub fn Quantity(comptime T: type, comptime d: Dimensions, comptime s: Scales) ty } test "Generate quantity" { - const Meter = Quantity(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = -3 })); - const Second = Quantity(f32, Dimensions.init(.{ .T = 1 }), Scales.init(.{ .T = .n })); + const Meter = Scalar(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = -3 })); + const Second = Scalar(f32, Dimensions.init(.{ .T = 1 }), Scales.init(.{ .T = .n })); const distance = Meter{ .value = 10 }; const time = Second{ .value = 2 }; @@ -179,7 +179,7 @@ test "Generate quantity" { } test "Add" { - const Meter = Quantity(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); + const Meter = Scalar(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); const distance = Meter{ .value = 10 }; const distance2 = Meter{ .value = 20 }; @@ -189,7 +189,7 @@ test "Add" { try std.testing.expectEqual(1, @TypeOf(added).dims.get(.L)); std.debug.print("KiloMeter {f} + {f} = {f} OK\n", .{ distance, distance2, added }); - const KiloMeter = Quantity(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .k })); + const KiloMeter = Scalar(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .k })); const distance3 = KiloMeter{ .value = 2 }; const added2 = distance.add(distance3); try std.testing.expectEqual(2010, added2.value); @@ -201,7 +201,7 @@ test "Add" { try std.testing.expectEqual(1, @TypeOf(added3).dims.get(.L)); std.debug.print("KiloMeter {f} + {f} = {f} OK\n", .{ distance3, distance, added3 }); - const KiloMeter_f = Quantity(f64, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .k })); + const KiloMeter_f = Scalar(f64, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .k })); const distance4 = KiloMeter_f{ .value = 2 }; const added4 = distance4.add(distance).to(KiloMeter_f); try std.testing.expectApproxEqAbs(2.01, added4.value, 0.000001); @@ -210,9 +210,9 @@ test "Add" { } test "Sub" { - const Meter = Quantity(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); - const KiloMeter = Quantity(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .k })); - const KiloMeter_f = Quantity(f64, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .k })); + const Meter = Scalar(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); + const KiloMeter = Scalar(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .k })); + const KiloMeter_f = Scalar(f64, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .k })); const a = Meter{ .value = 500 }; const b = Meter{ .value = 200 }; @@ -232,8 +232,8 @@ test "Sub" { } test "MulBy" { - const Meter = Quantity(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); - const Second = Quantity(f32, Dimensions.init(.{ .T = 1 }), Scales.init(.{})); + const Meter = Scalar(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); + const Second = Scalar(f32, Dimensions.init(.{ .T = 1 }), Scales.init(.{})); const d = Meter{ .value = 3.0 }; const t = Second{ .value = 4.0 }; @@ -253,8 +253,8 @@ test "MulBy" { } test "MulBy with scale" { - const KiloMeter = Quantity(f32, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .k })); - const KiloGram = Quantity(f32, Dimensions.init(.{ .M = 1 }), Scales.init(.{ .M = .k })); + const KiloMeter = Scalar(f32, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .k })); + const KiloGram = Scalar(f32, Dimensions.init(.{ .M = 1 }), Scales.init(.{ .M = .k })); const dist = KiloMeter{ .value = 2.0 }; const mass = KiloGram{ .value = 3.0 }; @@ -265,10 +265,10 @@ test "MulBy with scale" { } test "MulBy with type change" { - const Meter = Quantity(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .k })); - const Second = Quantity(f64, Dimensions.init(.{ .T = 1 }), Scales.init(.{})); - const KmSec = Quantity(i64, Dimensions.init(.{ .L = 1, .T = 1 }), Scales.init(.{ .L = .k })); - const KmSec_f = Quantity(f32, Dimensions.init(.{ .L = 1, .T = 1 }), Scales.init(.{ .L = .k })); + const Meter = Scalar(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .k })); + const Second = Scalar(f64, Dimensions.init(.{ .T = 1 }), Scales.init(.{})); + const KmSec = Scalar(i64, Dimensions.init(.{ .L = 1, .T = 1 }), Scales.init(.{ .L = .k })); + const KmSec_f = Scalar(f32, Dimensions.init(.{ .L = 1, .T = 1 }), Scales.init(.{ .L = .k })); const d = Meter{ .value = 3.0 }; const t = Second{ .value = 4.0 }; @@ -283,8 +283,8 @@ test "MulBy with type change" { } test "MulBy small" { - const Meter = Quantity(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .n })); - const Second = Quantity(f32, Dimensions.init(.{ .T = 1 }), Scales.init(.{})); + const Meter = Scalar(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .n })); + const Second = Scalar(f32, Dimensions.init(.{ .T = 1 }), Scales.init(.{})); const d = Meter{ .value = 3.0 }; const t = Second{ .value = 4.0 }; @@ -297,8 +297,8 @@ test "MulBy small" { } test "Scale" { - const Meter = Quantity(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); - const Second = Quantity(f32, Dimensions.init(.{ .T = 1 }), Scales.init(.{})); + const Meter = Scalar(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); + const Second = Scalar(f32, Dimensions.init(.{ .T = 1 }), Scales.init(.{})); const d = Meter{ .value = 7 }; const scaled = d.scale(3); @@ -313,8 +313,8 @@ test "Scale" { } test "Chained: velocity and acceleration" { - const Meter = Quantity(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); - const Second = Quantity(f32, Dimensions.init(.{ .T = 1 }), Scales.init(.{})); + const Meter = Scalar(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); + const Second = Scalar(f32, Dimensions.init(.{ .T = 1 }), Scales.init(.{})); const dist = Meter{ .value = 100.0 }; const t1 = Second{ .value = 5.0 }; @@ -333,8 +333,8 @@ test "Chained: velocity and acceleration" { } test "DivBy integer exact" { - const Meter = Quantity(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); - const Second = Quantity(f32, Dimensions.init(.{ .T = 1 }), Scales.init(.{})); + const Meter = Scalar(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); + const Second = Scalar(f32, Dimensions.init(.{ .T = 1 }), Scales.init(.{})); const dist = Meter{ .value = 120 }; const time = Second{ .value = 4 }; @@ -347,9 +347,9 @@ test "DivBy integer exact" { } test "Conversion chain: km -> m -> cm" { - const KiloMeter = Quantity(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .k })); - const Meter = Quantity(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); - const CentiMeter = Quantity(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .c })); + const KiloMeter = Scalar(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .k })); + const Meter = Scalar(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); + const CentiMeter = Scalar(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .c })); const km = KiloMeter{ .value = 15 }; const m = km.to(Meter); @@ -361,9 +361,9 @@ test "Conversion chain: km -> m -> cm" { } test "Conversion: hours -> minutes -> seconds" { - const Hour = Quantity(i128, Dimensions.init(.{ .T = 1 }), Scales.init(.{ .T = .hour })); - const Minute = Quantity(i128, Dimensions.init(.{ .T = 1 }), Scales.init(.{ .T = .min })); - const Second = Quantity(i128, Dimensions.init(.{ .T = 1 }), Scales.init(.{})); + const Hour = Scalar(i128, Dimensions.init(.{ .T = 1 }), Scales.init(.{ .T = .hour })); + const Minute = Scalar(i128, Dimensions.init(.{ .T = 1 }), Scales.init(.{ .T = .min })); + const Second = Scalar(i128, Dimensions.init(.{ .T = 1 }), Scales.init(.{})); const h = Hour{ .value = 1.0 }; const min = h.to(Minute); @@ -375,7 +375,7 @@ test "Conversion: hours -> minutes -> seconds" { } test "Negative values" { - const Meter = Quantity(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); + const Meter = Scalar(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); const a = Meter{ .value = 5 }; const b = Meter{ .value = 20 }; @@ -385,12 +385,12 @@ test "Negative values" { } test "Format Quantity" { - const MeterPerSecondSq = Quantity( + const MeterPerSecondSq = Scalar( f32, Dimensions.init(.{ .L = 1, .T = -2 }), Scales.init(.{ .T = .n }), ); - const KgMeterPerSecond = Quantity( + const KgMeterPerSecond = Scalar( f32, Dimensions.init(.{ .M = 1, .L = 1, .T = -1 }), Scales.init(.{ .M = .k }), @@ -477,9 +477,9 @@ test "Benchmark" { comptime var tidx: usize = 0; inline for (Types, TNames) |T, tname| { - const M = Quantity(T, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); - const KM = Quantity(T, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .k })); - const S = Quantity(T, Dimensions.init(.{ .T = 1 }), Scales.init(.{})); + const M = Scalar(T, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); + const KM = Scalar(T, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .k })); + const S = Scalar(T, Dimensions.init(.{ .T = 1 }), Scales.init(.{})); inline for (Ops, 0..) |op_name, oidx| { var samples: [SAMPLES]f64 = undefined; @@ -595,8 +595,8 @@ test "Overhead Analysis: Quantity vs Native" { var native_total_ns: f64 = 0; var quantity_total_ns: f64 = 0; - const M = Quantity(T, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); - const S = Quantity(T, Dimensions.init(.{ .T = 1 }), Scales.init(.{})); + const M = Scalar(T, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); + const S = Scalar(T, Dimensions.init(.{ .T = 1 }), Scales.init(.{})); for (0..SAMPLES) |_| { // --- 1. Benchmark Native --- @@ -719,9 +719,9 @@ test "Cross-Type Overhead Analysis: Quantity vs Native" { var native_total_ns: f64 = 0; var quantity_total_ns: f64 = 0; - const M1 = Quantity(T1, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); - const M2 = Quantity(T2, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); - const S2 = Quantity(T2, Dimensions.init(.{ .T = 1 }), Scales.init(.{})); + const M1 = Scalar(T1, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); + const M2 = Scalar(T2, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); + const S2 = Scalar(T2, Dimensions.init(.{ .T = 1 }), Scales.init(.{})); for (0..SAMPLES) |_| { // --- 1. Benchmark Native (Cast T2 to T1, then math) --- diff --git a/src/QuantityVec.zig b/src/Vector.zig similarity index 81% rename from src/QuantityVec.zig rename to src/Vector.zig index ac67df0..a56447d 100644 --- a/src/QuantityVec.zig +++ b/src/Vector.zig @@ -1,13 +1,13 @@ const std = @import("std"); const hlp = @import("helper.zig"); -const Quantity = @import("Quantity.zig").Quantity; +const Scalar = @import("Scalar.zig").Scalar; const Scales = @import("Scales.zig"); const UnitScale = Scales.UnitScale; const Dimensions = @import("Dimensions.zig"); const Dimension = Dimensions.Dimension; -pub fn QuantityVec(comptime len: usize, comptime Q: type) type { +pub fn Vector(comptime len: usize, comptime Q: type) type { const T = Q.ValueType; const d: Dimensions = Q.dims; const s: Scales = Q.scales; @@ -16,7 +16,7 @@ pub fn QuantityVec(comptime len: usize, comptime Q: type) type { data: [len]T, const Self = @This(); - pub const QuantityType = Q; + pub const ScalarType = Q; pub const ValueType = T; pub const dims: Dimensions = d; pub const scales = s; @@ -30,21 +30,21 @@ pub fn QuantityVec(comptime len: usize, comptime Q: type) type { return .{ .data = data }; } - pub fn add(self: Self, rhs: anytype) QuantityVec(len, Quantity(T, d, s.min(@TypeOf(rhs).scales))) { + pub fn add(self: Self, rhs: anytype) Vector(len, Scalar(T, d, s.min(@TypeOf(rhs).scales))) { const Tr = @TypeOf(rhs); - var res: QuantityVec(len, Quantity(T, d, s.min(Tr.scales))) = undefined; + var res: Vector(len, Scalar(T, d, s.min(Tr.scales))) = undefined; for (self.data, 0..) |v, i| { - const q = (Q{ .value = v }).add(Tr.QuantityType{ .value = rhs.data[i] }); + const q = (Q{ .value = v }).add(Tr.ScalarType{ .value = rhs.data[i] }); res.data[i] = q.value; } return res; } - pub fn sub(self: Self, rhs: anytype) QuantityVec(len, Quantity(T, d, s.min(@TypeOf(rhs).scales))) { + pub fn sub(self: Self, rhs: anytype) Vector(len, Scalar(T, d, s.min(@TypeOf(rhs).scales))) { const Tr = @TypeOf(rhs); - var res: QuantityVec(len, Quantity(T, d, s.min(Tr.scales))) = undefined; + var res: Vector(len, Scalar(T, d, s.min(Tr.scales))) = undefined; for (self.data, 0..) |v, i| { - const q = (Q{ .value = v }).sub(Tr.QuantityType{ .value = rhs.data[i] }); + const q = (Q{ .value = v }).sub(Tr.ScalarType{ .value = rhs.data[i] }); res.data[i] = q.value; } return res; @@ -53,11 +53,11 @@ pub fn QuantityVec(comptime len: usize, comptime Q: type) type { pub fn divBy( self: Self, rhs: anytype, - ) QuantityVec(len, Quantity(T, d.sub(@TypeOf(rhs).dims), s.min(@TypeOf(rhs).scales))) { + ) Vector(len, Scalar(T, d.sub(@TypeOf(rhs).dims), s.min(@TypeOf(rhs).scales))) { const Tr = @TypeOf(rhs); - var res: QuantityVec(len, Quantity(T, d.sub(Tr.dims), s.min(Tr.scales))) = undefined; + var res: Vector(len, Scalar(T, d.sub(Tr.dims), s.min(Tr.scales))) = undefined; for (self.data, 0..) |v, i| { - const q = (Q{ .value = v }).divBy(Tr.QuantityType{ .value = rhs.data[i] }); + const q = (Q{ .value = v }).divBy(Tr.ScalarType{ .value = rhs.data[i] }); res.data[i] = q.value; } return res; @@ -66,11 +66,11 @@ pub fn QuantityVec(comptime len: usize, comptime Q: type) type { pub fn mulBy( self: Self, rhs: anytype, - ) QuantityVec(len, Quantity(T, d.add(@TypeOf(rhs).dims), s.min(@TypeOf(rhs).scales))) { + ) Vector(len, Scalar(T, d.add(@TypeOf(rhs).dims), s.min(@TypeOf(rhs).scales))) { const Tr = @TypeOf(rhs); - var res: QuantityVec(len, Quantity(T, d.add(Tr.dims), s.min(Tr.scales))) = undefined; + var res: Vector(len, Scalar(T, d.add(Tr.dims), s.min(Tr.scales))) = undefined; for (self.data, 0..) |v, i| { - const q = (Q{ .value = v }).mulBy(Tr.QuantityType{ .value = rhs.data[i] }); + const q = (Q{ .value = v }).mulBy(Tr.ScalarType{ .value = rhs.data[i] }); res.data[i] = q.value; } return res; @@ -79,8 +79,8 @@ pub fn QuantityVec(comptime len: usize, comptime Q: type) type { pub fn divByScalar( self: Self, scalar: anytype, - ) QuantityVec(len, Quantity(T, d.sub(@TypeOf(scalar).dims), s.min(@TypeOf(scalar).scales))) { - var res: QuantityVec(len, Quantity(T, d.sub(@TypeOf(scalar).dims), s.min(@TypeOf(scalar).scales))) = undefined; + ) Vector(len, Scalar(T, d.sub(@TypeOf(scalar).dims), s.min(@TypeOf(scalar).scales))) { + var res: Vector(len, Scalar(T, d.sub(@TypeOf(scalar).dims), s.min(@TypeOf(scalar).scales))) = undefined; for (self.data, 0..) |v, i| { const q = Q{ .value = v }; res.data[i] = q.divBy(scalar).value; @@ -91,8 +91,8 @@ pub fn QuantityVec(comptime len: usize, comptime Q: type) type { pub fn mulByScalar( self: Self, scalar: anytype, - ) QuantityVec(len, Quantity(T, d.add(@TypeOf(scalar).dims), s.min(@TypeOf(scalar).scales))) { - var res: QuantityVec(len, Quantity(T, d.add(@TypeOf(scalar).dims), s.min(@TypeOf(scalar).scales))) = undefined; + ) Vector(len, Scalar(T, d.add(@TypeOf(scalar).dims), s.min(@TypeOf(scalar).scales))) { + var res: Vector(len, Scalar(T, d.add(@TypeOf(scalar).dims), s.min(@TypeOf(scalar).scales))) = undefined; for (self.data, 0..) |v, i| { const q = Q{ .value = v }; res.data[i] = q.mulBy(scalar).value; @@ -116,8 +116,8 @@ pub fn QuantityVec(comptime len: usize, comptime Q: type) type { return res; } - pub fn to(self: Self, comptime DestQ: type) QuantityVec(len, DestQ) { - var res: QuantityVec(len, DestQ) = undefined; + pub fn to(self: Self, comptime DestQ: type) Vector(len, DestQ) { + var res: Vector(len, DestQ) = undefined; for (self.data, 0..) |v, i| { res.data[i] = (Q{ .value = v }).to(DestQ).value; } @@ -168,12 +168,12 @@ pub fn QuantityVec(comptime len: usize, comptime Q: type) type { } test "Format VectorX" { - const MeterPerSecondSq = Quantity( + const MeterPerSecondSq = Scalar( f32, Dimensions.init(.{ .L = 1, .T = -2 }), Scales.init(.{ .T = .n }), ); - const KgMeterPerSecond = Quantity( + const KgMeterPerSecond = Scalar( f32, Dimensions.init(.{ .M = 1, .L = 1, .T = -1 }), Scales.init(.{ .M = .k }), @@ -187,7 +187,7 @@ test "Format VectorX" { } test "VecX Init and Basic Arithmetic" { - const Meter = Quantity(i32, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); + const Meter = Scalar(i32, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); const Vec3M = Meter.Vec3; // Test zero, one, initDefault @@ -228,14 +228,14 @@ test "VecX Init and Basic Arithmetic" { } test "VecX Kinematics (Scalar Mul/Div)" { - const Meter = Quantity(i32, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); - const Second = Quantity(i32, Dimensions.init(.{ .T = 1 }), Scales.init(.{})); + const Meter = Scalar(i32, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); + const Second = Scalar(i32, Dimensions.init(.{ .T = 1 }), Scales.init(.{})); const Vec3M = Meter.Vec3; const pos = Vec3M{ .data = .{ 100, 200, 300 } }; const time = Second{ .value = 10 }; - // Vector divided by scalar Quantity (Velocity = Position / Time) + // Vector divided by scalar (Velocity = Position / Time) const vel = pos.divByScalar(time); try std.testing.expectEqual(10, vel.data[0]); try std.testing.expectEqual(20, vel.data[1]); @@ -243,7 +243,7 @@ test "VecX Kinematics (Scalar Mul/Div)" { try std.testing.expectEqual(1, @TypeOf(vel).dims.get(.L)); try std.testing.expectEqual(-1, @TypeOf(vel).dims.get(.T)); - // Vector multiplied by scalar Quantity (Position = Velocity * Time) + // Vector multiplied by scalar (Position = Velocity * Time) const new_pos = vel.mulByScalar(time); try std.testing.expectEqual(100, new_pos.data[0]); try std.testing.expectEqual(200, new_pos.data[1]); @@ -253,7 +253,7 @@ test "VecX Kinematics (Scalar Mul/Div)" { } test "VecX Element-wise Math and Scaling" { - const Meter = Quantity(i32, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); + const Meter = Scalar(i32, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); const Vec3M = Meter.Vec3; const v1 = Vec3M{ .data = .{ 10, 20, 30 } }; @@ -274,8 +274,8 @@ test "VecX Element-wise Math and Scaling" { } test "VecX Conversions" { - const KiloMeter = Quantity(i32, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .k })); - const Meter = Quantity(i32, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); + const KiloMeter = Scalar(i32, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .k })); + const Meter = Scalar(i32, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); const v_km = KiloMeter.Vec3{ .data = .{ 1, 2, 3 } }; const v_m = v_km.to(Meter); @@ -290,8 +290,8 @@ test "VecX Conversions" { } test "VecX Length" { - const MeterInt = Quantity(i32, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); - const MeterFloat = Quantity(f32, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); + const MeterInt = Scalar(i32, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); + const MeterFloat = Scalar(f32, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); // Integer length (using your custom isqrt) // 3-4-5 triangle on XY plane @@ -305,7 +305,7 @@ test "VecX Length" { try std.testing.expectApproxEqAbs(@as(f32, 5.0), v_float.length(), 1e-4); } -test "Benchmark QuantityVec ops" { +test "Benchmark Vector ops" { const Io = std.Io; const ITERS: usize = 10_000; const SAMPLES: usize = 10; @@ -350,7 +350,7 @@ test "Benchmark QuantityVec ops" { std.debug.print( \\ - \\ QuantityVec benchmark — {d} iterations, {d} samples/cell + \\ Vector benchmark — {d} iterations, {d} samples/cell \\ (Results in ns/op) \\ \\┌─────────────┬──────┬─────────┬─────────┬─────────┐ @@ -369,9 +369,9 @@ test "Benchmark QuantityVec ops" { std.debug.print("│ {s:<11} │ {s:<4} │", .{ op_name, tname }); inline for (Lengths) |len| { - const Q_base = Quantity(T, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); - const Q_time = Quantity(T, Dimensions.init(.{ .T = 1 }), Scales.init(.{})); - const V = QuantityVec(len, Q_base); + const Q_base = Scalar(T, Dimensions.init(.{ .L = 1 }), Scales.init(.{})); + const Q_time = Scalar(T, Dimensions.init(.{ .T = 1 }), Scales.init(.{})); + const V = Vector(len, Q_base); var samples: [SAMPLES]f64 = undefined; diff --git a/src/main.zig b/src/main.zig index fc4c409..015d36f 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,16 +1,16 @@ const std = @import("std"); -pub const Quantity = @import("Quantity.zig").Quantity; -pub const QuantityVec = @import("QuantityVec.zig").QuantityVec; +pub const Scalar = @import("Scalar.zig").Scalar; +pub const Vector = @import("Vector.zig").Vector; pub const Dimensions = @import("Dimensions.zig"); pub const Scales = @import("Scales.zig"); -pub const Base = @import("BaseQuantities.zig"); +pub const Base = @import("Base.zig"); test { - _ = @import("Quantity.zig"); - _ = @import("QuantityVec.zig"); + _ = @import("Scalar.zig"); + _ = @import("Vector.zig"); _ = @import("Dimensions.zig"); _ = @import("Scales.zig"); - _ = @import("BaseQuantities.zig"); + _ = @import("Base.zig"); _ = @import("helper.zig"); }