scirs2-core 0.1.0-alpha.3

Core utilities and common functionality for SciRS2
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
//! # Physical and Mathematical Constants
//!
//! This module provides a comprehensive set of physical and mathematical constants for scientific computing,
//! closely aligning with SciPy's `constants` module to ensure compatibility and ease of migration.
//!
//! ## Mathematical Constants
//!
//! ```
//! use scirs2_core::constants::math::*;
//! assert!((PI - 3.14159265358979).abs() < 1e-14);
//! assert!((GOLDEN_RATIO - 1.618033988749895).abs() < 1e-14);
//! ```
//!
//! ## Physical Constants
//!
//! ```
//! use scirs2_core::constants::physical::*;
//! // Speed of light in vacuum (m/s)
//! assert_eq!(SPEED_OF_LIGHT, 299_792_458.0);
//! ```
//!
//! ## Unit Prefixes
//!
//! ```
//! use scirs2_core::constants::prefixes::*;
//! // SI prefixes
//! assert_eq!(KILO, 1e3);
//! // Binary prefixes
//! assert_eq!(KIBI, 1024.0);
//! ```
//!
//! ## Unit Conversions
//!
//! ```
//! use scirs2_core::constants::conversions::*;
//! // Length conversions
//! assert!((MILE_TO_METER - 1609.344).abs() < 1e-10);
//! ```
//!
//! ## Constants Database
//!
//! The module includes a comprehensive set of physical constants with their values, units, and precision.
//! This aligns with SciPy's `physical_constants` dictionary.

/// Mathematical constants
pub mod math {
    /// Pi (π)
    pub const PI: f64 = std::f64::consts::PI;

    /// Euler's number (e)
    pub const E: f64 = std::f64::consts::E;

    /// Euler-Mascheroni constant (γ)
    pub const EULER: f64 = 0.577_215_664_901_532_9;

    /// Golden ratio (φ)
    pub const GOLDEN: f64 = 1.618_033_988_749_895;

    /// Golden ratio (φ) - alias for GOLDEN
    pub const GOLDEN_RATIO: f64 = GOLDEN;

    /// Square root of 2
    pub const SQRT2: f64 = std::f64::consts::SQRT_2;

    /// Square root of π
    pub const SQRTPI: f64 = 1.772_453_850_905_516;

    /// Natural logarithm of 2
    pub const LN2: f64 = std::f64::consts::LN_2;

    /// Natural logarithm of 10
    pub const LN10: f64 = std::f64::consts::LN_10;
}

/// Physical constants (SI units)
pub mod physical {
    /// Speed of light in vacuum (m/s)
    pub const SPEED_OF_LIGHT: f64 = 299_792_458.0;

    /// Speed of light in vacuum (m/s) - alias for SPEED_OF_LIGHT
    pub const C: f64 = SPEED_OF_LIGHT;

    /// Magnetic constant (vacuum permeability) (N/A²)
    pub const MAGNETIC_CONSTANT: f64 = 1.25663706212e-6;

    /// Magnetic constant (vacuum permeability) (N/A²) - alias for MAGNETIC_CONSTANT
    pub const MU_0: f64 = MAGNETIC_CONSTANT;

    /// Electric constant (vacuum permittivity) (F/m)
    pub const ELECTRIC_CONSTANT: f64 = 8.8541878128e-12;

    /// Electric constant (vacuum permittivity) (F/m) - alias for ELECTRIC_CONSTANT
    pub const EPSILON_0: f64 = ELECTRIC_CONSTANT;

    /// Gravitational constant (m³/kg/s²)
    pub const GRAVITATIONAL_CONSTANT: f64 = 6.67430e-11;

    /// Gravitational constant (m³/kg/s²) - alias for GRAVITATIONAL_CONSTANT
    pub const G: f64 = GRAVITATIONAL_CONSTANT;

    /// Standard acceleration of gravity (m/s²)
    pub const STANDARD_GRAVITY: f64 = 9.80665;

    /// Standard acceleration of gravity (m/s²) - alias for STANDARD_GRAVITY
    pub const G_ACCEL: f64 = STANDARD_GRAVITY;

    /// Planck constant (J·s)
    pub const PLANCK: f64 = 6.62607015e-34;

    /// Planck constant (J·s) - alias for PLANCK
    pub const H: f64 = PLANCK;

    /// Reduced Planck constant (J·s)
    pub const REDUCED_PLANCK: f64 = 1.054571817e-34;

    /// Reduced Planck constant (J·s) - alias for REDUCED_PLANCK
    pub const HBAR: f64 = REDUCED_PLANCK;

    /// Elementary charge (C)
    pub const ELEMENTARY_CHARGE: f64 = 1.602176634e-19;

    /// Elementary charge (C) - alias for ELEMENTARY_CHARGE
    pub const E_CHARGE: f64 = ELEMENTARY_CHARGE;

    /// Electron mass (kg)
    pub const ELECTRON_MASS: f64 = 9.1093837015e-31;

    /// Electron mass (kg) - alias for ELECTRON_MASS
    pub const M_E: f64 = ELECTRON_MASS;

    /// Proton mass (kg)
    pub const PROTON_MASS: f64 = 1.67262192369e-27;

    /// Proton mass (kg) - alias for PROTON_MASS
    pub const M_P: f64 = PROTON_MASS;

    /// Neutron mass (kg)
    pub const NEUTRON_MASS: f64 = 1.67492749804e-27;

    /// Neutron mass (kg) - alias for NEUTRON_MASS
    pub const M_N: f64 = NEUTRON_MASS;

    /// Atomic mass constant (kg)
    pub const ATOMIC_MASS: f64 = 1.66053906660e-27;

    /// Atomic mass constant (kg) - alias for ATOMIC_MASS
    pub const M_U: f64 = ATOMIC_MASS;

    /// Atomic mass constant (kg) - alias for ATOMIC_MASS
    pub const U: f64 = ATOMIC_MASS;

    /// Fine-structure constant (dimensionless)
    pub const FINE_STRUCTURE: f64 = 7.2973525693e-3;

    /// Fine-structure constant (dimensionless) - alias for FINE_STRUCTURE
    pub const ALPHA: f64 = FINE_STRUCTURE;

    /// Rydberg constant (1/m)
    pub const RYDBERG: f64 = 10973731.568160;

    /// Avogadro constant (1/mol)
    pub const AVOGADRO: f64 = 6.02214076e23;

    /// Avogadro constant (1/mol) - alias for AVOGADRO
    pub const N_A: f64 = AVOGADRO;

    /// Gas constant (J/(mol·K))
    pub const GAS_CONSTANT: f64 = 8.31446261815324;

    /// Gas constant (J/(mol·K)) - alias for GAS_CONSTANT
    pub const R: f64 = GAS_CONSTANT;

    /// Boltzmann constant (J/K)
    pub const BOLTZMANN: f64 = 1.380649e-23;

    /// Boltzmann constant (J/K) - alias for BOLTZMANN
    pub const K: f64 = BOLTZMANN;

    /// Stefan-Boltzmann constant (W/(m²·K⁴))
    pub const STEFAN_BOLTZMANN: f64 = 5.670374419e-8;

    /// Stefan-Boltzmann constant (W/(m²·K⁴)) - alias for STEFAN_BOLTZMANN
    pub const SIGMA: f64 = STEFAN_BOLTZMANN;

    /// Wien wavelength displacement law constant (m·K)
    pub const WIEN: f64 = 2.897771955e-3;

    /// Electron volt (J)
    pub const ELECTRON_VOLT: f64 = 1.602176634e-19;

    /// Electron volt (J) - alias for ELECTRON_VOLT
    pub const EV: f64 = ELECTRON_VOLT;

    /// Astronomical unit (m)
    pub const ASTRONOMICAL_UNIT: f64 = 1.495978707e11;

    /// Astronomical unit (m) - alias for ASTRONOMICAL_UNIT
    pub const AU: f64 = ASTRONOMICAL_UNIT;

    /// Light year (m)
    pub const LIGHT_YEAR: f64 = 9.4607304725808e15;

    /// Parsec (m)
    pub const PARSEC: f64 = 3.085_677_581_491_367e16;
}

/// SI prefixes and binary prefixes
pub mod prefixes {
    /// SI prefixes
    pub mod si {
        /// Quetta (10^30)
        pub const QUETTA: f64 = 1e30;

        /// Ronna (10^27)
        pub const RONNA: f64 = 1e27;

        /// Yotta (10^24)
        pub const YOTTA: f64 = 1e24;

        /// Zetta (10^21)
        pub const ZETTA: f64 = 1e21;

        /// Exa (10^18)
        pub const EXA: f64 = 1e18;

        /// Peta (10^15)
        pub const PETA: f64 = 1e15;

        /// Tera (10^12)
        pub const TERA: f64 = 1e12;

        /// Giga (10^9)
        pub const GIGA: f64 = 1e9;

        /// Mega (10^6)
        pub const MEGA: f64 = 1e6;

        /// Kilo (10^3)
        pub const KILO: f64 = 1e3;

        /// Hecto (10^2)
        pub const HECTO: f64 = 1e2;

        /// Deka (10^1)
        pub const DEKA: f64 = 1e1;

        /// Deci (10^-1)
        pub const DECI: f64 = 1e-1;

        /// Centi (10^-2)
        pub const CENTI: f64 = 1e-2;

        /// Milli (10^-3)
        pub const MILLI: f64 = 1e-3;

        /// Micro (10^-6)
        pub const MICRO: f64 = 1e-6;

        /// Nano (10^-9)
        pub const NANO: f64 = 1e-9;

        /// Pico (10^-12)
        pub const PICO: f64 = 1e-12;

        /// Femto (10^-15)
        pub const FEMTO: f64 = 1e-15;

        /// Atto (10^-18)
        pub const ATTO: f64 = 1e-18;

        /// Zepto (10^-21)
        pub const ZEPTO: f64 = 1e-21;

        /// Yocto (10^-24)
        pub const YOCTO: f64 = 1e-24;

        /// Ronto (10^-27)
        pub const RONTO: f64 = 1e-27;

        /// Quecto (10^-30)
        pub const QUECTO: f64 = 1e-30;
    }

    /// Re-exports for ease of use
    pub use si::*;

    /// Binary prefixes
    pub mod binary {
        /// Kibi (2^10)
        pub const KIBI: f64 = 1024.0;

        /// Mebi (2^20)
        pub const MEBI: f64 = 1_048_576.0;

        /// Gibi (2^30)
        pub const GIBI: f64 = 1_073_741_824.0;

        /// Tebi (2^40)
        pub const TEBI: f64 = 1_099_511_627_776.0;

        /// Pebi (2^50)
        pub const PEBI: f64 = 1_125_899_906_842_624.0;

        /// Exbi (2^60)
        pub const EXBI: f64 = 1_152_921_504_606_846_976.0;

        /// Zebi (2^70)
        pub const ZEBI: f64 = 1_180_591_620_717_411_303_424.0;

        /// Yobi (2^80)
        pub const YOBI: f64 = 1_208_925_819_614_629_174_706_176.0;
    }

    /// Re-exports for ease of use
    pub use binary::*;
}

/// Unit conversions
pub mod conversions {
    /// Angular conversions
    pub mod angle {
        use crate::constants::math::PI;

        /// Degrees to radians conversion factor
        pub const DEG_TO_RAD: f64 = PI / 180.0;

        /// Radians to degrees conversion factor
        pub const RAD_TO_DEG: f64 = 180.0 / PI;

        /// Degree in radians
        pub const DEGREE: f64 = DEG_TO_RAD;

        /// Arc minute in radians
        pub const ARCMIN: f64 = DEGREE / 60.0;

        /// Arc minute in radians - alias for ARCMIN
        pub const ARCMINUTE: f64 = ARCMIN;

        /// Arc second in radians
        pub const ARCSEC: f64 = ARCMIN / 60.0;

        /// Arc second in radians - alias for ARCSEC
        pub const ARCSECOND: f64 = ARCSEC;
    }

    /// Re-exports for ease of use
    pub use angle::*;

    /// Time conversions
    pub mod time {
        /// Minute in seconds
        pub const MINUTE: f64 = 60.0;

        /// Hour in seconds
        pub const HOUR: f64 = 60.0 * MINUTE;

        /// Day in seconds
        pub const DAY: f64 = 24.0 * HOUR;

        /// Week in seconds
        pub const WEEK: f64 = 7.0 * DAY;

        /// Year (365 days) in seconds
        pub const YEAR: f64 = 365.0 * DAY;

        /// Julian year (365.25 days) in seconds
        pub const JULIAN_YEAR: f64 = 365.25 * DAY;
    }

    /// Re-exports for ease of use
    pub use time::*;

    /// Length conversions
    pub mod length {
        /// Base unit - meter
        pub const METER: f64 = 1.0;

        /// Inch in meters
        pub const INCH: f64 = 0.0254;

        /// Foot in meters
        pub const FOOT: f64 = 12.0 * INCH;

        /// Yard in meters
        pub const YARD: f64 = 3.0 * FOOT;

        /// Mile in meters
        pub const MILE: f64 = 1760.0 * YARD;

        /// Mil in meters
        pub const MIL: f64 = INCH / 1000.0;

        /// Point in meters (typography)
        pub const POINT: f64 = INCH / 72.0;

        /// Point in meters - alias for POINT
        pub const PT: f64 = POINT;

        /// Survey foot in meters
        pub const SURVEY_FOOT: f64 = 1200.0 / 3937.0;

        /// Survey mile in meters
        pub const SURVEY_MILE: f64 = 5280.0 * SURVEY_FOOT;

        /// Nautical mile in meters
        pub const NAUTICAL_MILE: f64 = 1852.0;

        /// Fermi in meters (1e-15 m)
        pub const FERMI: f64 = 1e-15;

        /// Angstrom in meters (1e-10 m)
        pub const ANGSTROM: f64 = 1e-10;

        /// Micron in meters (1e-6 m)
        pub const MICRON: f64 = 1e-6;

        /// Conversions from units to meters
        pub const INCH_TO_METER: f64 = INCH;
        pub const FOOT_TO_METER: f64 = FOOT;
        pub const YARD_TO_METER: f64 = YARD;
        pub const MILE_TO_METER: f64 = MILE;
    }

    /// Re-exports for ease of use
    pub use length::*;

    /// Mass conversions
    pub mod mass {
        /// Gram in kilograms
        pub const GRAM: f64 = 1e-3;

        /// Metric ton in kilograms
        pub const METRIC_TON: f64 = 1e3;

        /// Grain in kilograms
        pub const GRAIN: f64 = 64.79891e-6;

        /// Pound (avoirdupois) in kilograms
        pub const POUND: f64 = 7000.0 * GRAIN;

        /// Pound in kilograms - alias for POUND
        pub const LB: f64 = POUND;

        /// One inch version of a slug in kilograms
        pub const BLOB: f64 = POUND * 9.80665 / 0.0254;

        /// One inch version of a slug in kilograms - alias for BLOB
        pub const SLINCH: f64 = BLOB;

        /// One slug in kilograms
        pub const SLUG: f64 = BLOB / 12.0;

        /// Ounce in kilograms
        pub const OUNCE: f64 = POUND / 16.0;

        /// Ounce in kilograms - alias for OUNCE
        pub const OZ: f64 = OUNCE;

        /// Stone in kilograms
        pub const STONE: f64 = 14.0 * POUND;

        /// Long ton in kilograms
        pub const LONG_TON: f64 = 2240.0 * POUND;

        /// Short ton in kilograms
        pub const SHORT_TON: f64 = 2000.0 * POUND;

        /// Troy ounce in kilograms
        pub const TROY_OUNCE: f64 = 480.0 * GRAIN;

        /// Troy pound in kilograms
        pub const TROY_POUND: f64 = 12.0 * TROY_OUNCE;

        /// Carat in kilograms
        pub const CARAT: f64 = 200e-6;

        /// Conversions from units to kilograms
        pub const POUND_TO_KG: f64 = POUND;
    }

    /// Re-exports for ease of use
    pub use mass::*;

    /// Pressure conversions
    pub mod pressure {
        /// Standard atmosphere in pascals
        pub const ATMOSPHERE: f64 = 101325.0;

        /// Standard atmosphere in pascals - alias for ATMOSPHERE
        pub const ATM: f64 = ATMOSPHERE;

        /// Bar in pascals
        pub const BAR: f64 = 1e5;

        /// Torr (mmHg) in pascals
        pub const TORR: f64 = ATMOSPHERE / 760.0;

        /// Torr (mmHg) in pascals - alias for TORR
        pub const MMHG: f64 = TORR;

        /// PSI (pound-force per square inch) in pascals
        pub const PSI: f64 = POUND_FORCE / (INCH * INCH);

        // Required for PSI definition
        use super::force::POUND_FORCE;
        use super::length::INCH;
    }

    /// Re-exports for ease of use
    pub use pressure::*;

    /// Area conversions
    pub mod area {
        use super::length::FOOT;

        /// Hectare in square meters
        pub const HECTARE: f64 = 1e4;

        /// Acre in square meters
        pub const ACRE: f64 = 43560.0 * FOOT * FOOT;
    }

    /// Re-exports for ease of use
    pub use area::*;

    /// Volume conversions
    pub mod volume {
        use super::length::INCH;

        /// Liter in cubic meters
        pub const LITER: f64 = 1e-3;

        /// Liter in cubic meters - alias for LITER
        pub const LITRE: f64 = LITER;

        /// US gallon in cubic meters
        pub const GALLON_US: f64 = 231.0 * INCH * INCH * INCH;

        /// US gallon in cubic meters - alias for GALLON_US
        pub const GALLON: f64 = GALLON_US;

        /// Imperial gallon in cubic meters
        pub const GALLON_IMP: f64 = 4.54609e-3;

        /// US fluid ounce in cubic meters
        pub const FLUID_OUNCE_US: f64 = GALLON_US / 128.0;

        /// US fluid ounce in cubic meters - alias for FLUID_OUNCE_US
        pub const FLUID_OUNCE: f64 = FLUID_OUNCE_US;

        /// Imperial fluid ounce in cubic meters
        pub const FLUID_OUNCE_IMP: f64 = GALLON_IMP / 160.0;

        /// Barrel in cubic meters (for oil)
        pub const BARREL: f64 = 42.0 * GALLON_US;

        /// Barrel in cubic meters - alias for BARREL
        pub const BBL: f64 = BARREL;

        /// Gallons (US) to cubic meters
        pub const GALLON_TO_CUBIC_METER: f64 = GALLON_US;
    }

    /// Re-exports for ease of use
    pub use volume::*;

    /// Speed conversions
    pub mod speed {
        use super::length::{MILE, NAUTICAL_MILE};
        use super::time::HOUR;

        /// Kilometers per hour in meters per second
        pub const KMH: f64 = 1e3 / 3600.0;

        /// Miles per hour in meters per second
        pub const MPH: f64 = MILE / HOUR;

        /// Mach (approx., at 15°C, 1 atm) in meters per second
        pub const MACH: f64 = 340.5;

        /// Mach (approx., at 15°C, 1 atm) in meters per second - alias for MACH
        pub const SPEED_OF_SOUND: f64 = MACH;

        /// Knot in meters per second
        pub const KNOT: f64 = NAUTICAL_MILE / HOUR;
    }

    /// Re-exports for ease of use
    pub use speed::*;

    /// Temperature conversions
    pub mod temperature {
        /// Zero of Celsius scale in Kelvin
        pub const ZERO_CELSIUS: f64 = 273.15;

        /// One Fahrenheit (only for differences) in Kelvin
        pub const DEGREE_FAHRENHEIT: f64 = 1.0 / 1.8;

        /// Convert temperature from one scale to another
        ///
        /// # Arguments
        ///
        /// * `value` - Temperature value to convert
        /// * `from_scale` - Source scale: "celsius", "kelvin", "fahrenheit", or "rankine"
        /// * `to_scale` - Target scale: "celsius", "kelvin", "fahrenheit", or "rankine"
        ///
        /// # Returns
        ///
        /// Converted temperature value
        ///
        /// # Examples
        ///
        /// ```
        /// use scirs2_core::constants::conversions::temperature::convert_temperature;
        ///
        /// let celsius = 100.0;
        /// let kelvin = convert_temperature(celsius, "celsius", "kelvin");
        /// assert!((kelvin - 373.15).abs() < 1e-10);
        ///
        /// let fahrenheit = convert_temperature(celsius, "celsius", "fahrenheit");
        /// assert!((fahrenheit - 212.0).abs() < 1e-10);
        /// ```
        pub fn convert_temperature(value: f64, from_scale: &str, to_scale: &str) -> f64 {
            // Convert from source scale to Kelvin
            let kelvin = match from_scale.to_lowercase().as_str() {
                "celsius" | "c" => value + ZERO_CELSIUS,
                "kelvin" | "k" => value,
                "fahrenheit" | "f" => (value - 32.0) * 5.0 / 9.0 + ZERO_CELSIUS,
                "rankine" | "r" => value * 5.0 / 9.0,
                _ => panic!("Unsupported 'from' scale: {}. Supported scales are Celsius, Kelvin, Fahrenheit, and Rankine", from_scale),
            };

            // Convert from Kelvin to target scale
            match to_scale.to_lowercase().as_str() {
                "celsius" | "c" => kelvin - ZERO_CELSIUS,
                "kelvin" | "k" => kelvin,
                "fahrenheit" | "f" => (kelvin - ZERO_CELSIUS) * 9.0 / 5.0 + 32.0,
                "rankine" | "r" => kelvin * 9.0 / 5.0,
                _ => panic!("Unsupported 'to' scale: {}. Supported scales are Celsius, Kelvin, Fahrenheit, and Rankine", to_scale),
            }
        }
    }

    /// Re-exports for ease of use
    pub use temperature::*;

    /// Energy conversions
    pub mod energy {
        use super::mass::POUND;
        use super::temperature::DEGREE_FAHRENHEIT;
        use crate::constants::physical::ELEMENTARY_CHARGE;

        /// Electron volt in joules
        pub const ELECTRON_VOLT: f64 = ELEMENTARY_CHARGE;

        /// Electron volt in joules - alias for ELECTRON_VOLT
        pub const EV: f64 = ELECTRON_VOLT;

        /// Calorie (thermochemical) in joules
        pub const CALORIE_TH: f64 = 4.184;

        /// Calorie (thermochemical) in joules - alias for CALORIE_TH
        pub const CALORIE: f64 = CALORIE_TH;

        /// Calorie (International Steam Table calorie, 1956) in joules
        pub const CALORIE_IT: f64 = 4.1868;

        /// Erg in joules
        pub const ERG: f64 = 1e-7;

        /// British thermal unit (International Steam Table) in joules
        pub const BTU_IT: f64 = POUND * DEGREE_FAHRENHEIT * CALORIE_IT / 1e-3;

        /// British thermal unit (International Steam Table) in joules - alias for BTU_IT
        pub const BTU: f64 = BTU_IT;

        /// British thermal unit (thermochemical) in joules
        pub const BTU_TH: f64 = POUND * DEGREE_FAHRENHEIT * CALORIE_TH / 1e-3;

        /// Ton of TNT in joules
        pub const TON_TNT: f64 = 1e9 * CALORIE_TH;
    }

    /// Re-exports for ease of use
    pub use energy::*;

    /// Power conversions
    pub mod power {
        use super::length::FOOT;
        use super::mass::POUND;

        /// Standard gravity constant (m/s²)
        const STANDARD_GRAVITY: f64 = 9.80665;

        /// Horsepower in watts
        pub const HORSEPOWER: f64 = 550.0 * FOOT * POUND * STANDARD_GRAVITY;

        /// Horsepower in watts - alias for HORSEPOWER
        pub const HP: f64 = HORSEPOWER;
    }

    /// Re-exports for ease of use
    pub use power::*;

    /// Force conversions
    pub mod force {
        use super::mass::POUND;

        /// Standard gravity constant (m/s²)
        const STANDARD_GRAVITY: f64 = 9.80665;

        /// Dyne in newtons
        pub const DYNE: f64 = 1e-5;

        /// Dyne in newtons - alias for DYNE
        pub const DYN: f64 = DYNE;

        /// Pound force in newtons
        pub const POUND_FORCE: f64 = POUND * STANDARD_GRAVITY;

        /// Pound force in newtons - alias for POUND_FORCE
        pub const LBF: f64 = POUND_FORCE;

        /// Kilogram force in newtons
        pub const KILOGRAM_FORCE: f64 = STANDARD_GRAVITY;

        /// Kilogram force in newtons - alias for KILOGRAM_FORCE
        pub const KGF: f64 = KILOGRAM_FORCE;
    }

    /// Re-exports for ease of use
    pub use force::*;

    /// Optics conversions and functions
    pub mod optics {
        use crate::constants::physical::SPEED_OF_LIGHT;

        /// Convert wavelength to optical frequency
        ///
        /// # Arguments
        ///
        /// * `wavelength` - Wavelength in meters
        ///
        /// # Returns
        ///
        /// Equivalent optical frequency in Hz
        ///
        /// # Examples
        ///
        /// ```
        /// use scirs2_core::constants::conversions::optics::lambda2nu;
        /// use scirs2_core::constants::physical::SPEED_OF_LIGHT;
        ///
        /// let wavelength = 1.0;  // 1 meter
        /// let frequency = lambda2nu(wavelength);
        /// assert!((frequency - SPEED_OF_LIGHT).abs() < 1e-10);
        /// ```
        pub fn lambda2nu(wavelength: f64) -> f64 {
            SPEED_OF_LIGHT / wavelength
        }

        /// Convert optical frequency to wavelength
        ///
        /// # Arguments
        ///
        /// * `frequency` - Optical frequency in Hz
        ///
        /// # Returns
        ///
        /// Equivalent wavelength in meters
        ///
        /// # Examples
        ///
        /// ```
        /// use scirs2_core::constants::conversions::optics::nu2lambda;
        /// use scirs2_core::constants::physical::SPEED_OF_LIGHT;
        ///
        /// let frequency = SPEED_OF_LIGHT;  // c Hz
        /// let wavelength = nu2lambda(frequency);
        /// assert!((wavelength - 1.0).abs() < 1e-10);  // 1 meter
        /// ```
        pub fn nu2lambda(frequency: f64) -> f64 {
            SPEED_OF_LIGHT / frequency
        }
    }

    /// Re-exports for ease of use
    pub use optics::*;
}

/// Access to the `physical` module constants
pub use self::physical::*;

/// Access to commonly used math constants
pub use self::math::*;

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_mathematical_constants() {
        assert_eq!(math::PI, std::f64::consts::PI);
        assert_eq!(math::E, std::f64::consts::E);
        assert!((math::GOLDEN - 1.618033988749895).abs() < 1e-14);
    }

    #[test]
    fn test_physical_constants() {
        assert_eq!(physical::SPEED_OF_LIGHT, 299_792_458.0);
        assert_eq!(physical::C, physical::SPEED_OF_LIGHT);
        assert_eq!(physical::ELECTRON_VOLT, 1.602176634e-19);
    }

    #[test]
    fn test_unit_conversions() {
        // Use approx_eq for floating point comparisons with very small difference
        assert!((conversions::MILE_TO_METER - 1609.344).abs() < 1e-10);
        assert_eq!(conversions::INCH, 0.0254);
        assert_eq!(conversions::METER, 1.0);
    }

    #[test]
    fn test_temperature_conversion() {
        let celsius = 100.0;
        let kelvin = conversions::temperature::convert_temperature(celsius, "celsius", "kelvin");
        assert!((kelvin - 373.15).abs() < 1e-10);

        let fahrenheit =
            conversions::temperature::convert_temperature(celsius, "celsius", "fahrenheit");
        assert!((fahrenheit - 212.0).abs() < 1e-10);

        let back_to_celsius =
            conversions::temperature::convert_temperature(fahrenheit, "fahrenheit", "celsius");
        assert!((back_to_celsius - celsius).abs() < 1e-10);
    }

    #[test]
    fn test_prefix_values() {
        assert_eq!(prefixes::KILO, 1e3);
        assert_eq!(prefixes::MEGA, 1e6);
        assert_eq!(prefixes::MICRO, 1e-6);

        assert_eq!(prefixes::KIBI, 1024.0);
        assert_eq!(prefixes::MEBI, 1024.0 * 1024.0);
    }

    #[test]
    fn test_optics_conversions() {
        let wavelength = 1.0; // 1 meter
        let frequency = conversions::optics::lambda2nu(wavelength);
        assert!((frequency - physical::SPEED_OF_LIGHT).abs() < 1e-10);

        let back_to_wavelength = conversions::optics::nu2lambda(frequency);
        assert!((back_to_wavelength - wavelength).abs() < 1e-10);
    }
}