relativistic-simulator 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. relativistic_simulator-0.1.0/.gitignore +20 -0
  2. relativistic_simulator-0.1.0/.python-version +1 -0
  3. relativistic_simulator-0.1.0/CHANGELOG.md +21 -0
  4. relativistic_simulator-0.1.0/LICENSE +21 -0
  5. relativistic_simulator-0.1.0/PKG-INFO +196 -0
  6. relativistic_simulator-0.1.0/README.md +164 -0
  7. relativistic_simulator-0.1.0/docs/benchmarks.md +11 -0
  8. relativistic_simulator-0.1.0/docs/physics.md +65 -0
  9. relativistic_simulator-0.1.0/docs/validation.md +15 -0
  10. relativistic_simulator-0.1.0/examples/basic_simulation.py +43 -0
  11. relativistic_simulator-0.1.0/examples/benchmark.py +21 -0
  12. relativistic_simulator-0.1.0/examples/generate_dataset.py +87 -0
  13. relativistic_simulator-0.1.0/examples/high_beta.py +46 -0
  14. relativistic_simulator-0.1.0/pyproject.toml +66 -0
  15. relativistic_simulator-0.1.0/src/relativistic_simulator/__init__.py +120 -0
  16. relativistic_simulator-0.1.0/src/relativistic_simulator/_common.py +168 -0
  17. relativistic_simulator-0.1.0/src/relativistic_simulator/classical.py +105 -0
  18. relativistic_simulator-0.1.0/src/relativistic_simulator/constants.py +16 -0
  19. relativistic_simulator-0.1.0/src/relativistic_simulator/dataset.py +389 -0
  20. relativistic_simulator-0.1.0/src/relativistic_simulator/dynamics.py +348 -0
  21. relativistic_simulator-0.1.0/src/relativistic_simulator/exceptions.py +55 -0
  22. relativistic_simulator-0.1.0/src/relativistic_simulator/plotting.py +204 -0
  23. relativistic_simulator-0.1.0/src/relativistic_simulator/relativity.py +361 -0
  24. relativistic_simulator-0.1.0/src/relativistic_simulator/simulator.py +126 -0
  25. relativistic_simulator-0.1.0/src/relativistic_simulator/trajectory.py +189 -0
  26. relativistic_simulator-0.1.0/src/relativistic_simulator/validation.py +411 -0
  27. relativistic_simulator-0.1.0/tests/conftest.py +60 -0
  28. relativistic_simulator-0.1.0/tests/test_dataset.py +155 -0
  29. relativistic_simulator-0.1.0/tests/test_dynamics.py +156 -0
  30. relativistic_simulator-0.1.0/tests/test_plotting.py +66 -0
  31. relativistic_simulator-0.1.0/tests/test_relativity.py +240 -0
  32. relativistic_simulator-0.1.0/tests/test_simulator.py +141 -0
  33. relativistic_simulator-0.1.0/tests/test_validation.py +134 -0
  34. relativistic_simulator-0.1.0/uv.lock +1341 -0
@@ -0,0 +1,20 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+
9
+ # Virtual environments
10
+ .venv
11
+ .wheel-test
12
+
13
+ # Example and benchmark output
14
+ examples/output/
15
+ benchmark-results.txt
16
+
17
+ # Tool caches
18
+ .pytest_cache/
19
+ .ruff_cache/
20
+ .mypy_cache/
@@ -0,0 +1 @@
1
+ 3.12
@@ -0,0 +1,21 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented here.
4
+
5
+ ## [0.1.0] - 2026-09-13
6
+
7
+ ### Added
8
+
9
+ - 1D special-relativistic massive-particle dynamics under constant force.
10
+ - Numerically stable relativistic kinematics, energy, momentum, and proper-time functions.
11
+ - Exact analytical solver and independent RK4 cross-check integrator.
12
+ - Vectorized reproducible NumPy dataset generation.
13
+ - Quantitative physical validation reports.
14
+ - Optional pandas conversion and matplotlib plotting utilities.
15
+ - Pytest test suite, examples, and uv/PyPI packaging configuration.
16
+
17
+ ### Scientific scope
18
+
19
+ The model assumes flat Minkowski spacetime, one spatial dimension, constant rest mass,
20
+ and an externally applied constant 1D force. It does not model gravity, fields,
21
+ radiation reaction, quantum effects, or faster-than-light trajectories.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mayank
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,196 @@
1
+ Metadata-Version: 2.5
2
+ Name: relativistic-simulator
3
+ Version: 0.1.0
4
+ Summary: 1D special-relativistic constant-force massive-particle dynamics simulator: a ground-truth physics engine for machine-learning research.
5
+ Project-URL: Homepage, https://github.com/mayank/relativistic-simulator
6
+ Project-URL: Repository, https://github.com/mayank/relativistic-simulator
7
+ Project-URL: Changelog, https://github.com/mayank/relativistic-simulator/blob/main/CHANGELOG.md
8
+ Author: Mayank
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: machine-learning,physics,relativity,scientific-computing,simulation,special-relativity,synthetic-data
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Scientific/Engineering :: Physics
21
+ Classifier: Typing :: Typed
22
+ Requires-Python: >=3.10
23
+ Requires-Dist: numpy>=1.24
24
+ Provides-Extra: all
25
+ Requires-Dist: matplotlib>=3.5; extra == 'all'
26
+ Requires-Dist: pandas>=2.0; extra == 'all'
27
+ Provides-Extra: pandas
28
+ Requires-Dist: pandas>=2.0; extra == 'pandas'
29
+ Provides-Extra: plot
30
+ Requires-Dist: matplotlib>=3.5; extra == 'plot'
31
+ Description-Content-Type: text/markdown
32
+
33
+ # relativistic-simulator
34
+
35
+ Research-grade, lightweight Python simulator for **1D special-relativistic massive-particle dynamics under a constant external force**.
36
+
37
+ This package is the ground-truth physics engine for a synthetic-data/ML research pipeline. It generates data from known equations; it does not discover physics and it does not contain an ML model.
38
+
39
+ ## Scientific assumptions
40
+
41
+ - flat Minkowski spacetime and special relativity;
42
+ - one spatial dimension;
43
+ - constant rest mass;
44
+ - externally applied constant 1D force;
45
+ - SI units;
46
+ - no gravity, curved spacetime, electromagnetic-field model, radiation reaction, quantum effects, or FTL dynamics.
47
+
48
+ The governing equation is `dp/dt = F` with `p = gamma*m*v`, not classical `F = m*a`.
49
+
50
+ ## Installation
51
+
52
+ ```bash
53
+ pip install relativistic-simulator
54
+ pip install "relativistic-simulator[all]" # optional pandas + matplotlib
55
+ ```
56
+
57
+ Development uses uv:
58
+
59
+ ```bash
60
+ uv sync
61
+ ```
62
+
63
+ ## Quick start
64
+
65
+ ```python
66
+ from relativistic_simulator import C, simulate
67
+
68
+ result = simulate(
69
+ mass=1000.0, force=1e6, initial_velocity=0.9 * C,
70
+ duration=100.0, dt=0.01,
71
+ )
72
+
73
+ print(result.beta)
74
+ print(result.gamma)
75
+ print(result.momentum)
76
+ print(result.kinetic_energy)
77
+ print(result.total_energy)
78
+ print(result.proper_time)
79
+ print(result.validate().summary())
80
+ ```
81
+
82
+ `simulate()` returns a `Trajectory` exposing `time`, `position`, `velocity`, `beta`, `gamma`, `momentum`, `kinetic_energy`, `total_energy`, and `proper_time`, plus `to_numpy()`, `to_dict()`, `to_dataframe()`, and `final_state()`.
83
+
84
+ ## Equations and numerical method
85
+
86
+ For initial momentum `p0 = gamma0*m*v0`:
87
+
88
+ ```text
89
+ p(t) = p0 + F*t
90
+ q(t) = p(t)/(m*c)
91
+ gamma(t) = hypot(1, q(t))
92
+ v(t) = c*q(t)/gamma(t)
93
+ E(t) = c*hypot(m*c, p(t))
94
+ K(t) = p(t)^2*c^2 / (E(t) + m*c^2)
95
+ x(t) = x0 + c*t*(q(t) + q0)/(gamma(t) + gamma0) [F != 0]
96
+ ```
97
+
98
+ The position formula is algebraically equivalent to `(K-K0)/F`, but avoids catastrophic cancellation at high beta and small impulse. Proper time uses `dτ = dt/gamma` and a stable `log1p` rapidity-increment form. `simulate(method="numerical")` supplies an independent RK4 cross-check.
99
+
100
+ See [`docs/physics.md`](docs/physics.md) for derivations and precision details.
101
+
102
+ ## Relativity API
103
+
104
+ ```python
105
+ from relativistic_simulator import (
106
+ C, beta_from_velocity, velocity_from_beta, gamma_from_beta,
107
+ gamma_from_velocity, momentum_from_velocity, velocity_from_momentum,
108
+ energy_from_velocity, energy_from_momentum,
109
+ kinetic_energy_from_velocity, kinetic_energy_from_momentum, rest_energy,
110
+ )
111
+
112
+ gamma = gamma_from_beta(0.99999)
113
+ ```
114
+
115
+ All functions accept scalars and NumPy arrays where practical. Massive-particle states must satisfy `abs(v) < C` and `abs(beta) < 1`; invalid states raise typed exceptions and are never silently clipped.
116
+
117
+ ## Dataset generation
118
+
119
+ ```python
120
+ from relativistic_simulator import generate_dataset
121
+
122
+ dataset = generate_dataset(
123
+ n_samples=100_000,
124
+ mass_range=(100.0, 10_000.0),
125
+ force_range=(1e4, 1e7),
126
+ beta_range=(0.0, 0.8),
127
+ time_range=(0.0, 100.0),
128
+ random_seed=42,
129
+ )
130
+
131
+ dataset.to_csv("train.csv")
132
+ print(dataset.input_columns)
133
+ print(dataset.output_columns)
134
+ print(dataset.validate().summary())
135
+ ```
136
+
137
+ Generation is fully vectorized with NumPy and uses `numpy.random.default_rng`, so seeded datasets are reproducible without global randomness. Inputs are `mass`, `force`, `initial_velocity`, `initial_beta`, and `time`; targets are exact `position`, `velocity`, `beta`, `gamma`, `momentum`, `kinetic_energy`, `total_energy`, and `proper_time`.
138
+
139
+ Regimes are configurable rather than hard-coded:
140
+
141
+ ```python
142
+ low = generate_dataset(beta_range=(0.0, 0.5), random_seed=1)
143
+ relativistic = generate_dataset(beta_range=(0.5, 0.9), random_seed=2)
144
+ ultra = generate_dataset(beta_range=(0.9, 0.9999), random_seed=3)
145
+ training = generate_dataset(beta_range=(0.0, 0.8), random_seed=42)
146
+ extrapolation = generate_dataset(beta_range=(0.8, 0.9999), random_seed=43)
147
+ ```
148
+
149
+ ## Validation
150
+
151
+ `validate_trajectory` and `validate_dataset` report quantitative errors for `p = gamma*m*v`, `E = gamma*m*c²`, the energy-momentum invariant, central finite differences for `dp/dt` and `dx/dt`, proper time, initial conditions, velocity bound, and `tau <= t`. They use independent routes rather than merely repeating the generating expression.
152
+
153
+ ```python
154
+ report = result.validate()
155
+ print(report.max_energy_momentum_error)
156
+ print(report.max_force_error)
157
+ print(report.max_velocity_difference_error)
158
+ print(report.passed)
159
+ ```
160
+
161
+ ## Optional plotting and classical comparison
162
+
163
+ ```python
164
+ from relativistic_simulator.plotting import plot_trajectory, plot_gamma_vs_beta
165
+ plot_trajectory(result, path="trajectory.png", show=False)
166
+ plot_gamma_vs_beta(path="gamma.png", show=False)
167
+ ```
168
+
169
+ The `classical` module is comparison-only: it provides Newtonian `p=m*v`, `K=0.5*m*v**2`, and `x=x0+v0*t+0.5*(F/m)*t**2`. It is not used by the relativistic engine.
170
+
171
+ ## Examples
172
+
173
+ ```bash
174
+ uv run python examples/basic_simulation.py
175
+ uv run python examples/high_beta.py
176
+ uv run python examples/generate_dataset.py
177
+ uv run python examples/benchmark.py
178
+ ```
179
+
180
+ ## Development, testing, and build
181
+
182
+ ```bash
183
+ uv sync
184
+ uv run pytest
185
+ uv build
186
+ ```
187
+
188
+ The suite covers high beta through `0.99999c`, invalid physical states, exact/RK4 agreement, vectorization, reproducibility, dataset validation, and optional plotting. `uv build` creates wheel and source distributions in `dist/`. Review and test those artifacts before any deliberate `uv publish`.
189
+
190
+ ## Precision and limitations
191
+
192
+ The numerical representation is IEEE-754 float64. The package rejects `|v| >= c` rather than clipping and rejects states for which floating-point arithmetic cannot represent a strictly subluminal velocity. It does not model gravity, curved spacetime, electromagnetic fields, variable mass, radiation reaction, quantum effects, or FTL/spacelike trajectories.
193
+
194
+ ## License
195
+
196
+ MIT License. See [`LICENSE`](LICENSE).
@@ -0,0 +1,164 @@
1
+ # relativistic-simulator
2
+
3
+ Research-grade, lightweight Python simulator for **1D special-relativistic massive-particle dynamics under a constant external force**.
4
+
5
+ This package is the ground-truth physics engine for a synthetic-data/ML research pipeline. It generates data from known equations; it does not discover physics and it does not contain an ML model.
6
+
7
+ ## Scientific assumptions
8
+
9
+ - flat Minkowski spacetime and special relativity;
10
+ - one spatial dimension;
11
+ - constant rest mass;
12
+ - externally applied constant 1D force;
13
+ - SI units;
14
+ - no gravity, curved spacetime, electromagnetic-field model, radiation reaction, quantum effects, or FTL dynamics.
15
+
16
+ The governing equation is `dp/dt = F` with `p = gamma*m*v`, not classical `F = m*a`.
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ pip install relativistic-simulator
22
+ pip install "relativistic-simulator[all]" # optional pandas + matplotlib
23
+ ```
24
+
25
+ Development uses uv:
26
+
27
+ ```bash
28
+ uv sync
29
+ ```
30
+
31
+ ## Quick start
32
+
33
+ ```python
34
+ from relativistic_simulator import C, simulate
35
+
36
+ result = simulate(
37
+ mass=1000.0, force=1e6, initial_velocity=0.9 * C,
38
+ duration=100.0, dt=0.01,
39
+ )
40
+
41
+ print(result.beta)
42
+ print(result.gamma)
43
+ print(result.momentum)
44
+ print(result.kinetic_energy)
45
+ print(result.total_energy)
46
+ print(result.proper_time)
47
+ print(result.validate().summary())
48
+ ```
49
+
50
+ `simulate()` returns a `Trajectory` exposing `time`, `position`, `velocity`, `beta`, `gamma`, `momentum`, `kinetic_energy`, `total_energy`, and `proper_time`, plus `to_numpy()`, `to_dict()`, `to_dataframe()`, and `final_state()`.
51
+
52
+ ## Equations and numerical method
53
+
54
+ For initial momentum `p0 = gamma0*m*v0`:
55
+
56
+ ```text
57
+ p(t) = p0 + F*t
58
+ q(t) = p(t)/(m*c)
59
+ gamma(t) = hypot(1, q(t))
60
+ v(t) = c*q(t)/gamma(t)
61
+ E(t) = c*hypot(m*c, p(t))
62
+ K(t) = p(t)^2*c^2 / (E(t) + m*c^2)
63
+ x(t) = x0 + c*t*(q(t) + q0)/(gamma(t) + gamma0) [F != 0]
64
+ ```
65
+
66
+ The position formula is algebraically equivalent to `(K-K0)/F`, but avoids catastrophic cancellation at high beta and small impulse. Proper time uses `dτ = dt/gamma` and a stable `log1p` rapidity-increment form. `simulate(method="numerical")` supplies an independent RK4 cross-check.
67
+
68
+ See [`docs/physics.md`](docs/physics.md) for derivations and precision details.
69
+
70
+ ## Relativity API
71
+
72
+ ```python
73
+ from relativistic_simulator import (
74
+ C, beta_from_velocity, velocity_from_beta, gamma_from_beta,
75
+ gamma_from_velocity, momentum_from_velocity, velocity_from_momentum,
76
+ energy_from_velocity, energy_from_momentum,
77
+ kinetic_energy_from_velocity, kinetic_energy_from_momentum, rest_energy,
78
+ )
79
+
80
+ gamma = gamma_from_beta(0.99999)
81
+ ```
82
+
83
+ All functions accept scalars and NumPy arrays where practical. Massive-particle states must satisfy `abs(v) < C` and `abs(beta) < 1`; invalid states raise typed exceptions and are never silently clipped.
84
+
85
+ ## Dataset generation
86
+
87
+ ```python
88
+ from relativistic_simulator import generate_dataset
89
+
90
+ dataset = generate_dataset(
91
+ n_samples=100_000,
92
+ mass_range=(100.0, 10_000.0),
93
+ force_range=(1e4, 1e7),
94
+ beta_range=(0.0, 0.8),
95
+ time_range=(0.0, 100.0),
96
+ random_seed=42,
97
+ )
98
+
99
+ dataset.to_csv("train.csv")
100
+ print(dataset.input_columns)
101
+ print(dataset.output_columns)
102
+ print(dataset.validate().summary())
103
+ ```
104
+
105
+ Generation is fully vectorized with NumPy and uses `numpy.random.default_rng`, so seeded datasets are reproducible without global randomness. Inputs are `mass`, `force`, `initial_velocity`, `initial_beta`, and `time`; targets are exact `position`, `velocity`, `beta`, `gamma`, `momentum`, `kinetic_energy`, `total_energy`, and `proper_time`.
106
+
107
+ Regimes are configurable rather than hard-coded:
108
+
109
+ ```python
110
+ low = generate_dataset(beta_range=(0.0, 0.5), random_seed=1)
111
+ relativistic = generate_dataset(beta_range=(0.5, 0.9), random_seed=2)
112
+ ultra = generate_dataset(beta_range=(0.9, 0.9999), random_seed=3)
113
+ training = generate_dataset(beta_range=(0.0, 0.8), random_seed=42)
114
+ extrapolation = generate_dataset(beta_range=(0.8, 0.9999), random_seed=43)
115
+ ```
116
+
117
+ ## Validation
118
+
119
+ `validate_trajectory` and `validate_dataset` report quantitative errors for `p = gamma*m*v`, `E = gamma*m*c²`, the energy-momentum invariant, central finite differences for `dp/dt` and `dx/dt`, proper time, initial conditions, velocity bound, and `tau <= t`. They use independent routes rather than merely repeating the generating expression.
120
+
121
+ ```python
122
+ report = result.validate()
123
+ print(report.max_energy_momentum_error)
124
+ print(report.max_force_error)
125
+ print(report.max_velocity_difference_error)
126
+ print(report.passed)
127
+ ```
128
+
129
+ ## Optional plotting and classical comparison
130
+
131
+ ```python
132
+ from relativistic_simulator.plotting import plot_trajectory, plot_gamma_vs_beta
133
+ plot_trajectory(result, path="trajectory.png", show=False)
134
+ plot_gamma_vs_beta(path="gamma.png", show=False)
135
+ ```
136
+
137
+ The `classical` module is comparison-only: it provides Newtonian `p=m*v`, `K=0.5*m*v**2`, and `x=x0+v0*t+0.5*(F/m)*t**2`. It is not used by the relativistic engine.
138
+
139
+ ## Examples
140
+
141
+ ```bash
142
+ uv run python examples/basic_simulation.py
143
+ uv run python examples/high_beta.py
144
+ uv run python examples/generate_dataset.py
145
+ uv run python examples/benchmark.py
146
+ ```
147
+
148
+ ## Development, testing, and build
149
+
150
+ ```bash
151
+ uv sync
152
+ uv run pytest
153
+ uv build
154
+ ```
155
+
156
+ The suite covers high beta through `0.99999c`, invalid physical states, exact/RK4 agreement, vectorization, reproducibility, dataset validation, and optional plotting. `uv build` creates wheel and source distributions in `dist/`. Review and test those artifacts before any deliberate `uv publish`.
157
+
158
+ ## Precision and limitations
159
+
160
+ The numerical representation is IEEE-754 float64. The package rejects `|v| >= c` rather than clipping and rejects states for which floating-point arithmetic cannot represent a strictly subluminal velocity. It does not model gravity, curved spacetime, electromagnetic fields, variable mass, radiation reaction, quantum effects, or FTL/spacelike trajectories.
161
+
162
+ ## License
163
+
164
+ MIT License. See [`LICENSE`](LICENSE).
@@ -0,0 +1,11 @@
1
+ # Benchmarks
2
+
3
+ Run the benchmark yourself with:
4
+
5
+ ```bash
6
+ uv run python examples/benchmark.py
7
+ ```
8
+
9
+ The script reports wall-clock time, samples per second, and the NumPy storage footprint
10
+ for 10,000, 100,000, and 1,000,000 vectorized observations. Benchmark values are
11
+ machine-dependent and are intentionally not hard-coded in this document.
@@ -0,0 +1,65 @@
1
+ # Physics and numerical method
2
+
3
+ ## Model
4
+
5
+ The package models a massive particle in one spatial dimension in flat Minkowski
6
+ spacetime. Units are SI: mass in kg, force in N, position in m, velocity in m/s,
7
+ time in s, momentum in kg m/s, and energy in J. The speed of light is the exact
8
+ constant `C = 299792458.0 m/s`.
9
+
10
+ The dynamical law is
11
+
12
+ \[
13
+ \frac{dp}{dt}=F, \qquad p=\gamma m v,
14
+ \]
15
+
16
+ not `F = m a`.
17
+
18
+ ## Exact solution
19
+
20
+ For initial momentum \(p_0=\gamma_0mv_0\),
21
+
22
+ \[
23
+ p(t)=p_0+Ft,
24
+ \quad q=\frac{p}{mc},
25
+ \quad \gamma=\sqrt{1+q^2},
26
+ \quad v=c\frac{q}{\gamma}.
27
+ \]
28
+
29
+ The total and kinetic energies are
30
+
31
+ \[
32
+ E=\sqrt{m^2c^4+p^2c^2},\qquad
33
+ K=\frac{p^2c^2}{E+mc^2}.
34
+ \]
35
+
36
+ For nonzero force, position is evaluated in the cancellation-free form
37
+
38
+ \[
39
+ x(t)=x_0+ct\frac{q+q_0}{\gamma+\gamma_0}.
40
+ \]
41
+
42
+ This is algebraically equivalent to \(x_0+(K-K_0)/F\), but avoids subtracting two
43
+ large nearly equal kinetic energies in high-beta, small-impulse cases. For zero force,
44
+ \(x=x_0+v_0t\).
45
+
46
+ Proper time is accumulated from \(d\tau=dt/\gamma\). The implementation uses a
47
+ `log1p` rapidity-increment form, avoiding cancellation in
48
+ `asinh(q) - asinh(q0)` when the impulse is tiny compared with the initial momentum.
49
+
50
+ ## Numerical safety
51
+
52
+ - Inputs with `|v| >= c`, `|beta| >= 1`, nonpositive mass, nonfinite values, or invalid
53
+ integration steps raise typed exceptions.
54
+ - Values are never silently clipped to the light cone.
55
+ - `hypot` is used for square roots of sums of squares.
56
+ - `gamma - 1` and `E - mc²` are evaluated through rationalized identities.
57
+ - The exact solver is independent of the RK4 integrator used for cross-checking.
58
+
59
+ ## Validity limits
60
+
61
+ This is not a general relativistic engine. It excludes gravity, curved spacetime,
62
+ electromagnetic-field models, radiation reaction, variable mass, quantum effects,
63
+ and spacelike/FTL trajectories. Float64 precision also limits how close a represented
64
+ state can be to the light cone; such states are rejected if the computed velocity can
65
+ no longer be represented as strictly subluminal.
@@ -0,0 +1,15 @@
1
+ # Validation methodology
2
+
3
+ `validate_trajectory` and `validate_dataset` return measured errors rather than a
4
+ single opaque boolean. Checks include:
5
+
6
+ - `p = gamma*m*v`;
7
+ - `E = gamma*m*c²`;
8
+ - `E² - p²c² = m²c⁴`;
9
+ - central finite differences for `dp/dt = F` and `dx/dt = v`;
10
+ - trapezoidal integration of `dt/gamma` against proper time;
11
+ - initial conditions and `tau <= t`;
12
+ - independent RK4 versus analytical trajectory comparison in tests.
13
+
14
+ The finite-difference checks intentionally use interior central differences. One-sided
15
+ edge stencils can amplify floating-point roundoff even for bitwise-constant arrays.
@@ -0,0 +1,43 @@
1
+ """Example 1: basic simulation of a massive particle under constant force.
2
+
3
+ A 1000 kg object starting at rest, pushed by a constant 1e6 N force in +x
4
+ for 100 seconds. In the classical picture this would reach 1e5 m/s
5
+ (0.03% of c) after 100 s; the relativistic solution is essentially identical
6
+ because beta stays tiny.
7
+ """
8
+ from __future__ import annotations
9
+
10
+ import numpy as np
11
+
12
+ from relativistic_simulator import C, simulate
13
+
14
+ def main() -> None:
15
+ result = simulate(
16
+ mass=1000.0, # kg
17
+ force=1e6, # N
18
+ initial_velocity=0.0, # m/s (at rest)
19
+ duration=100.0, # s
20
+ dt=0.01, # s
21
+ )
22
+
23
+ final = result.final_state()
24
+ classical_v = (1e6 / 1000.0) * 100.0 # v = (F/m) * t, Newtonian
25
+ classical_K = 0.5 * 1000.0 * classical_v**2
26
+
27
+ print("Basic simulation: 1000 kg at rest, F = 1e6 N, t = 100 s")
28
+ print(f" n_points : {result.n_points}")
29
+ print(f" final position : {final['position']:.6e} m")
30
+ print(f" final velocity : {final['velocity']:.6e} m/s (beta = {final['beta']:.6e})")
31
+ print(f" classical velocity : {classical_v:.6e} m/s")
32
+ print(f" final gamma : {final['gamma']:.12f}")
33
+ print(f" final momentum : {final['momentum']:.6e} kg*m/s (classical m*v = {1000*classical_v:.6e})")
34
+ print(f" final kinetic energy: {final['kinetic_energy']:.6e} J (classical = {classical_K:.6e} J)")
35
+ print(f" proper time : {final['proper_time']:.9f} s (<= 100 s: {final['proper_time'] <= 100.0})")
36
+
37
+ report = result.validate()
38
+ print()
39
+ print(report.summary())
40
+
41
+
42
+ if __name__ == "__main__":
43
+ main()
@@ -0,0 +1,21 @@
1
+ """Measure vectorized dataset-generation throughput on the current machine."""
2
+ from __future__ import annotations
3
+
4
+ import time
5
+
6
+ from relativistic_simulator import generate_dataset
7
+
8
+
9
+ def main() -> None:
10
+ print(f"{'samples':>12} {'seconds':>12} {'samples/sec':>16} {'MiB':>12}")
11
+ print("-" * 56)
12
+ for n in (10_000, 100_000, 1_000_000):
13
+ start = time.perf_counter()
14
+ dataset = generate_dataset(n_samples=n, random_seed=42)
15
+ elapsed = time.perf_counter() - start
16
+ mib = dataset.to_numpy().nbytes / (1024.0**2)
17
+ print(f"{n:12,d} {elapsed:12.6f} {n / elapsed:16,.0f} {mib:12.2f}")
18
+
19
+
20
+ if __name__ == "__main__":
21
+ main()
@@ -0,0 +1,87 @@
1
+ """Example 3: generate a ground-truth dataset for the future ML experiment.
2
+
3
+ Research pipeline this supports (the ML part is NOT part of this package):
4
+
5
+ physics equations
6
+ -> relativistic-simulator (this package, exact physics)
7
+ -> thousands/millions of synthetic observations
8
+ -> (external) ML model
9
+ -> predictions on unseen ultra-relativistic regimes
10
+ -> comparison against exact physics
11
+
12
+ Here we generate:
13
+ * a training regime beta in (0.0, 0.8)
14
+ * an extrapolation regime beta in (0.8, 0.9999)
15
+ with a fixed random seed for reproducibility, and save both to CSV.
16
+ """
17
+ from __future__ import annotations
18
+
19
+ from pathlib import Path
20
+
21
+ import numpy as np
22
+
23
+ from relativistic_simulator import generate_dataset
24
+
25
+ OUTPUT_DIR = Path(__file__).parent / "output"
26
+ N_TRAIN = 100_000
27
+ N_EXTRAP = 20_000
28
+ SEED = 42
29
+
30
+
31
+ def main() -> None:
32
+ OUTPUT_DIR.mkdir(exist_ok=True)
33
+
34
+ print("Generating ground-truth data (exact physics, seeded) ...")
35
+ train = generate_dataset(
36
+ n_samples=N_TRAIN,
37
+ mass_range=(100.0, 10_000.0),
38
+ force_range=(1e4, 1e7),
39
+ beta_range=(0.0, 0.8), # training regime
40
+ time_range=(0.0, 100.0),
41
+ random_seed=SEED,
42
+ )
43
+ extrap = generate_dataset(
44
+ n_samples=N_EXTRAP,
45
+ mass_range=(100.0, 10_000.0),
46
+ force_range=(1e4, 1e7),
47
+ beta_range=(0.8, 0.9999), # unseen ultra-relativistic regime
48
+ time_range=(0.0, 100.0),
49
+ random_seed=SEED + 1,
50
+ )
51
+
52
+ train_csv = OUTPUT_DIR / "train_beta_0_0.8.csv"
53
+ extrap_csv = OUTPUT_DIR / "extrap_beta_0.8_0.9999.csv"
54
+ train.to_csv(str(train_csv))
55
+ extrap.to_csv(str(extrap_csv))
56
+
57
+ print()
58
+ print(f"train : {len(train):>7} rows, beta in [{train.initial_beta.min():.4f}, "
59
+ f"{train.initial_beta.max():.4f}] -> {train_csv.name}")
60
+ print(f"extrap : {len(extrap):>7} rows, beta in [{extrap.initial_beta.min():.4f}, "
61
+ f"{extrap.initial_beta.max():.4f}] -> {extrap_csv.name}")
62
+ print()
63
+ print("input columns :", train.input_columns)
64
+ print("target columns:", train.output_columns)
65
+
66
+ report = train.validate()
67
+ assert report.passed, report.summary()
68
+ print()
69
+ print(f"train physics validation: passed={report.passed}, "
70
+ f"max invariant err = {report.max_energy_momentum_error:.2e}, "
71
+ f"max momentum err = {report.max_momentum_relation_error:.2e}")
72
+
73
+ # Reproducibility check: same seed -> bitwise-identical data
74
+ again = generate_dataset(
75
+ n_samples=N_TRAIN,
76
+ mass_range=(100.0, 10_000.0),
77
+ force_range=(1e4, 1e7),
78
+ beta_range=(0.0, 0.8),
79
+ time_range=(0.0, 100.0),
80
+ random_seed=SEED,
81
+ )
82
+ assert np.array_equal(train.momentum, again.momentum)
83
+ print("reproducibility: same seed reproduces bitwise-identical data")
84
+
85
+
86
+ if __name__ == "__main__":
87
+ main()