scientific-computing-system 1.6.2__py3-none-any.whl

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 (97) hide show
  1. cds/__init__.py +102 -0
  2. cds/__main__.py +8 -0
  3. cds/_version.py +10 -0
  4. cds/cli/__init__.py +104 -0
  5. cds/cli/__main__.py +8 -0
  6. cds/cli/_handlers.py +405 -0
  7. cds/cli/_parser.py +156 -0
  8. cds/cli/_style.py +117 -0
  9. cds/core/__init__.py +5 -0
  10. cds/core/_numeric.py +92 -0
  11. cds/core/models.py +166 -0
  12. cds/data_analysis/__init__.py +30 -0
  13. cds/data_analysis/dataset.py +122 -0
  14. cds/data_analysis/loader.py +75 -0
  15. cds/data_analysis/pandas_io.py +108 -0
  16. cds/data_analysis/transform.py +36 -0
  17. cds/data_analysis/viz.py +88 -0
  18. cds/diffeq/__init__.py +29 -0
  19. cds/diffeq/_implicit.py +349 -0
  20. cds/diffeq/solvers.py +312 -0
  21. cds/graph/__init__.py +31 -0
  22. cds/graph/algorithms.py +399 -0
  23. cds/hypothesis/__init__.py +48 -0
  24. cds/hypothesis/evaluator.py +369 -0
  25. cds/hypothesis/generator.py +275 -0
  26. cds/knowledge/__init__.py +41 -0
  27. cds/knowledge/graph.py +489 -0
  28. cds/knowledge/notes.py +231 -0
  29. cds/knowledge/retrieval.py +167 -0
  30. cds/math_utils/__init__.py +41 -0
  31. cds/math_utils/calculus.py +40 -0
  32. cds/math_utils/linalg.py +461 -0
  33. cds/math_utils/special.py +167 -0
  34. cds/ml/__init__.py +25 -0
  35. cds/ml/clustering.py +190 -0
  36. cds/ml/decomposition.py +172 -0
  37. cds/ml/linear_models.py +225 -0
  38. cds/ml/neighbors.py +162 -0
  39. cds/ml/neural.py +204 -0
  40. cds/ml/preprocessing.py +131 -0
  41. cds/ml/tree.py +202 -0
  42. cds/modeling/__init__.py +40 -0
  43. cds/modeling/_base.py +210 -0
  44. cds/modeling/_nodes.py +526 -0
  45. cds/modeling/expression.py +81 -0
  46. cds/modeling/model.py +134 -0
  47. cds/modeling/solver.py +176 -0
  48. cds/montecarlo/__init__.py +21 -0
  49. cds/montecarlo/methods.py +272 -0
  50. cds/nlp/__init__.py +170 -0
  51. cds/nlp/attention.py +285 -0
  52. cds/nlp/autograd/__init__.py +70 -0
  53. cds/nlp/autograd/_grad.py +120 -0
  54. cds/nlp/autograd/ops.py +133 -0
  55. cds/nlp/autograd/tensor.py +298 -0
  56. cds/nlp/bpe.py +449 -0
  57. cds/nlp/data.py +70 -0
  58. cds/nlp/embed.py +190 -0
  59. cds/nlp/layers.py +259 -0
  60. cds/nlp/model.py +456 -0
  61. cds/nlp/optim.py +163 -0
  62. cds/nlp/training.py +167 -0
  63. cds/nlp/viz.py +254 -0
  64. cds/numerical_integration/__init__.py +31 -0
  65. cds/numerical_integration/quadrature.py +480 -0
  66. cds/optimization/__init__.py +18 -0
  67. cds/optimization/_metaheuristics.py +287 -0
  68. cds/optimization/minimize.py +425 -0
  69. cds/plot/__init__.py +49 -0
  70. cds/plot/_backend.py +32 -0
  71. cds/plot/charts.py +462 -0
  72. cds/probability/__init__.py +55 -0
  73. cds/probability/_advanced.py +283 -0
  74. cds/probability/distributions.py +236 -0
  75. cds/py.typed +0 -0
  76. cds/quantum/__init__.py +51 -0
  77. cds/quantum/circuit.py +92 -0
  78. cds/quantum/multi_qubit.py +255 -0
  79. cds/quantum/simulator.py +38 -0
  80. cds/scientific/__init__.py +34 -0
  81. cds/scientific/constants.py +35 -0
  82. cds/scientific/formulas.py +116 -0
  83. cds/signals/__init__.py +43 -0
  84. cds/signals/filters.py +421 -0
  85. cds/signals/processing.py +224 -0
  86. cds/stats/__init__.py +83 -0
  87. cds/stats/_distributions.py +102 -0
  88. cds/stats/descriptive.py +172 -0
  89. cds/stats/hypothesis_tests.py +403 -0
  90. cds/stats/nonparametric.py +131 -0
  91. cds/stats/regression.py +51 -0
  92. cds/stats/time_series.py +408 -0
  93. scientific_computing_system-1.6.2.dist-info/METADATA +741 -0
  94. scientific_computing_system-1.6.2.dist-info/RECORD +97 -0
  95. scientific_computing_system-1.6.2.dist-info/WHEEL +4 -0
  96. scientific_computing_system-1.6.2.dist-info/entry_points.txt +2 -0
  97. scientific_computing_system-1.6.2.dist-info/licenses/LICENSE +21 -0
cds/__init__.py ADDED
@@ -0,0 +1,102 @@
1
+ """
2
+ scientific-computing-system
3
+
4
+ Pure Python computational science system for research, simulation,
5
+ and scientific discovery.
6
+
7
+ Key features:
8
+ - Zero heavy dependencies (pure Python)
9
+ - Quantum simulation (single & multi-qubit with entanglement)
10
+ - Signal processing (FFT, 2D FFT, convolution, filtering)
11
+ - Optimization, statistics, probability, linear algebra
12
+ - Hypothesis generation for structured research ideas
13
+ - CLI for quick calculations and discovery workflows
14
+
15
+ All modules are designed to be readable, testable, and usable
16
+ for education, research, and custom scientific discovery workflows.
17
+
18
+ Usage:
19
+ import cds
20
+ print(cds.__version__)
21
+
22
+ from cds.quantum import ghz_state, is_entangled
23
+ from cds.hypothesis import generate_hypotheses
24
+ """
25
+
26
+ # Convenient top-level re-exports for common scientific tools
27
+ # Core modules
28
+ # Scientific computing modules
29
+ from cds import (
30
+ core,
31
+ data_analysis,
32
+ diffeq,
33
+ graph,
34
+ hypothesis,
35
+ knowledge,
36
+ math_utils,
37
+ ml,
38
+ modeling,
39
+ montecarlo,
40
+ nlp,
41
+ numerical_integration,
42
+ optimization,
43
+ plot,
44
+ probability,
45
+ quantum,
46
+ scientific,
47
+ signals,
48
+ stats,
49
+ )
50
+ from cds._version import __version__
51
+ from cds.scientific.constants import CONSTANTS, get_constant
52
+ from cds.scientific.formulas import (
53
+ centripetal_acceleration,
54
+ coulomb_force,
55
+ de_broglie_wavelength,
56
+ doppler_frequency,
57
+ escape_velocity,
58
+ gravitational_force,
59
+ ideal_gas_pressure,
60
+ kinetic_energy,
61
+ pendulum_period,
62
+ photon_energy,
63
+ schwarzschild_radius,
64
+ wave_frequency,
65
+ )
66
+
67
+ __all__ = [
68
+ "__version__",
69
+ "CONSTANTS",
70
+ "get_constant",
71
+ "kinetic_energy",
72
+ "gravitational_force",
73
+ "wave_frequency",
74
+ "ideal_gas_pressure",
75
+ "schwarzschild_radius",
76
+ "de_broglie_wavelength",
77
+ "escape_velocity",
78
+ "photon_energy",
79
+ "coulomb_force",
80
+ "centripetal_acceleration",
81
+ "pendulum_period",
82
+ "doppler_frequency",
83
+ "core",
84
+ "data_analysis",
85
+ "ml",
86
+ "diffeq",
87
+ "graph",
88
+ "hypothesis",
89
+ "knowledge",
90
+ "math_utils",
91
+ "modeling",
92
+ "montecarlo",
93
+ "nlp",
94
+ "numerical_integration",
95
+ "optimization",
96
+ "plot",
97
+ "probability",
98
+ "quantum",
99
+ "scientific",
100
+ "signals",
101
+ "stats",
102
+ ]
cds/__main__.py ADDED
@@ -0,0 +1,8 @@
1
+ """Allow running the CLI with `python -m cds`."""
2
+
3
+ import sys
4
+
5
+ from .cli import main
6
+
7
+ if __name__ == "__main__": # pragma: no cover
8
+ sys.exit(main())
cds/_version.py ADDED
@@ -0,0 +1,10 @@
1
+ # Static version source. Kept in lockstep with `version` in `pyproject.toml`.
2
+ # Bump both before tagging a release. See `pyproject.toml` for the release
3
+ # checklist. This file is committed (not generated) so mypy has a concrete
4
+ # `__version__: str` to resolve in fresh checkouts without git history.
5
+ from __future__ import annotations
6
+
7
+ __all__ = ["__version__", "version", "__version_tuple__", "version_tuple"]
8
+
9
+ __version__ = version = "1.6.2"
10
+ __version_tuple__ = version_tuple = (1, 6, 2)
cds/cli/__init__.py ADDED
@@ -0,0 +1,104 @@
1
+ """System command-line interface.
2
+
3
+ Pure-stdlib CLI built on :mod:`argparse`. It replaces the previous
4
+ ``typer``/``rich`` implementation so the whole ``cds`` package stays
5
+ zero-dependency at runtime. Rich-style colour is reproduced with small ANSI
6
+ escape helpers; the textual output (help text, table contents, prompts) is
7
+ preserved verbatim where the test suite asserts on it.
8
+
9
+ The package is split for maintainability:
10
+
11
+ - :mod:`cds.cli._style` — ANSI colour + ASCII table rendering
12
+ - :mod:`cds.cli._handlers` — one function per subcommand
13
+ - :mod:`cds.cli._parser` — argument-parser wiring
14
+
15
+ The entry point :func:`main` accepts an optional ``argv`` so tests can drive a
16
+ specific command without spawning a subprocess, and returns the integer exit
17
+ code instead of calling :func:`sys.exit` directly when ``argv`` is given.
18
+ """
19
+
20
+ from __future__ import annotations
21
+
22
+ import sys
23
+ from collections.abc import Sequence
24
+
25
+ from cds.cli._handlers import (
26
+ _cmd_benchmark,
27
+ _cmd_calc,
28
+ _cmd_constants,
29
+ _cmd_dashboard,
30
+ _cmd_hypothesis,
31
+ _cmd_info,
32
+ _cmd_integrate,
33
+ _cmd_modules,
34
+ _cmd_plot,
35
+ _cmd_prompt,
36
+ _cmd_sample,
37
+ _cmd_stats,
38
+ _cmd_version,
39
+ )
40
+ from cds.cli._parser import _build_parser, build_parser
41
+ from cds.cli._style import (
42
+ _format_table,
43
+ _print,
44
+ _render,
45
+ _supports_color,
46
+ _wrap,
47
+ )
48
+
49
+ __all__ = [
50
+ "main",
51
+ "build_parser",
52
+ "_build_parser",
53
+ "_format_table",
54
+ "_print",
55
+ "_render",
56
+ "_supports_color",
57
+ "_wrap",
58
+ "_cmd_benchmark",
59
+ "_cmd_calc",
60
+ "_cmd_constants",
61
+ "_cmd_dashboard",
62
+ "_cmd_hypothesis",
63
+ "_cmd_info",
64
+ "_cmd_integrate",
65
+ "_cmd_modules",
66
+ "_cmd_plot",
67
+ "_cmd_prompt",
68
+ "_cmd_sample",
69
+ "_cmd_stats",
70
+ "_cmd_version",
71
+ ]
72
+
73
+
74
+ def main(argv: Sequence[str] | None = None) -> int:
75
+ """CLI entry point. Returns the process exit code.
76
+
77
+ When ``argv`` is ``None`` (the normal ``cds`` invocation) it reads
78
+ :data:`sys.argv`; tests pass an explicit list so no subprocess is needed.
79
+
80
+ argparse raises :class:`SystemExit` for ``--help`` and usage errors. We
81
+ catch it here and surface its code as the return value so callers (tests
82
+ and ``__main__``) never see an exception — only an integer exit code.
83
+ """
84
+ parser = build_parser()
85
+ try:
86
+ args = parser.parse_args(argv)
87
+ except SystemExit as exc:
88
+ return int(exc.code) if isinstance(exc.code, int) else 0
89
+
90
+ if args.version:
91
+ from cds import __version__
92
+
93
+ _print(_render(f"[bold]System[/] version [cyan]{__version__}[/]"))
94
+ return 0
95
+
96
+ func = getattr(args, "func", None)
97
+ if func is None:
98
+ parser.print_help()
99
+ return 0
100
+ return int(func(args))
101
+
102
+
103
+ if __name__ == "__main__": # pragma: no cover
104
+ sys.exit(main())
cds/cli/__main__.py ADDED
@@ -0,0 +1,8 @@
1
+ """Allow ``python -m cds.cli`` to run the CLI directly."""
2
+
3
+ import sys
4
+
5
+ from cds.cli import main
6
+
7
+ if __name__ == "__main__": # pragma: no cover — exercised via subprocess
8
+ sys.exit(main())
cds/cli/_handlers.py ADDED
@@ -0,0 +1,405 @@
1
+ """Implementations of the ``cds`` subcommands.
2
+
3
+ Every handler takes the parsed :class:`argparse.Namespace` and returns an
4
+ integer exit code. Heavy imports stay function-local so ``cds --help`` (and
5
+ the whole parser build) never pays for modules a command does not use.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import argparse
11
+ import json
12
+ import os
13
+ import subprocess
14
+ import sys
15
+ from collections.abc import Callable
16
+ from pathlib import Path
17
+
18
+ from cds.cli._style import _format_table, _print, _render
19
+ from cds.core.models import Domain
20
+ from cds.hypothesis.generator import PromptTemplate, generate_hypotheses
21
+
22
+
23
+ def _cmd_version(args: argparse.Namespace) -> int:
24
+ """Show the installed System version."""
25
+ from cds import __version__
26
+
27
+ _print(_render(f"[bold]System[/] version [cyan]{__version__}[/]"))
28
+ return 0
29
+
30
+
31
+ def _cmd_hypothesis(args: argparse.Namespace) -> int:
32
+ """Generate scientific hypotheses for a research question."""
33
+ dom = Domain(args.domain)
34
+
35
+ if args.show_prompt:
36
+ prompt = PromptTemplate.render(args.question, dom, args.num)
37
+ _print(_render(f"[blue]{prompt}[/]"))
38
+ return 0
39
+
40
+ if args.dry_run:
41
+ _print(_render("[yellow]Dry run mode — no generation performed.[/]"))
42
+ _print(
43
+ _render(
44
+ f"Would generate {args.num} hypotheses for: "
45
+ f"[bold]{args.question}[/] in domain [cyan]{dom.value}[/]"
46
+ )
47
+ )
48
+ return 0
49
+
50
+ _print(_render(f"[bold]Generating hypotheses[/] for: [italic]{args.question}[/]"))
51
+ _print(_render(f"Domain: [cyan]{dom.value}[/] | Count: {args.num}\n"))
52
+
53
+ hypos = generate_hypotheses(args.question, domain=dom, n=args.num)
54
+
55
+ rows: list[list[str]] = []
56
+ for h in hypos:
57
+ stmt = h.statement[:90] + ("..." if len(h.statement) > 90 else "")
58
+ rows.append([h.id, stmt, f"{h.confidence:.2f}"])
59
+ _print(_format_table("Generated Hypotheses", ["ID", "Statement", "Confidence"], rows))
60
+
61
+ if hypos:
62
+ _print(_render("\n[bold]Detailed view of first hypothesis:[/]\n"))
63
+ _print(_render(f"[green]{hypos[0].to_markdown()}[/]"))
64
+
65
+ if args.output:
66
+ data = [h.to_dict() for h in hypos]
67
+ Path(args.output).write_text(json.dumps(data, indent=2, default=str))
68
+ _print(_render(f"\n[green]Saved to {args.output}[/]"))
69
+
70
+ return 0
71
+
72
+
73
+ def _cmd_prompt(args: argparse.Namespace) -> int:
74
+ """Print a ready-to-use prompt for a custom generator implementation."""
75
+ dom = Domain(args.domain)
76
+ prompt_text = PromptTemplate.render(args.question, dom, args.num)
77
+ _print(prompt_text)
78
+ return 0
79
+
80
+
81
+ def _cmd_info(args: argparse.Namespace) -> int:
82
+ """Show System info, module status, and System health."""
83
+ from cds import __version__
84
+
85
+ _print(_render("[bold]System (CDS)[/]"))
86
+ _print(_render("[dim]Pure Python scientific computing system[/]"))
87
+ _print("")
88
+ _print(_render("[bold green]Status:[/] Stable"))
89
+ _print(_render("[bold blue]Tests:[/] full suite green in CI (see badge)"))
90
+ _print(_render("[bold magenta]Deps:[/] 0 External (Pure Python core)"))
91
+ _print(_render(f"[bold cyan]Version:[/] {__version__}"))
92
+ _print("")
93
+ _print(_render("[bold]Architecture:[/]"))
94
+ _print(_render("[bold]Core Modules:[/]"))
95
+ for line in (
96
+ "quantum signals",
97
+ "math_utils stats",
98
+ "optimization montecarlo",
99
+ "hypothesis diffeq",
100
+ "graph data_analysis",
101
+ "ml probability",
102
+ "scientific numerical_integration",
103
+ "modeling knowledge",
104
+ "nlp plot (optional matplotlib)",
105
+ ):
106
+ _print(f" • {line}")
107
+ return 0
108
+
109
+
110
+ def _cmd_stats(args: argparse.Namespace) -> int:
111
+ """Descriptive statistics for a comma-separated number list."""
112
+ from cds.stats import mean, median, percentile, stdev, variance
113
+
114
+ try:
115
+ data = [float(x.strip()) for x in args.values.split(",")]
116
+ except ValueError:
117
+ _print(_render("[red]Error:[/] Values must be a comma-separated list of numbers."))
118
+ return 1
119
+ if not data: # pragma: no cover - split always yields at least one token
120
+ _print(_render("[red]Error:[/] empty list."))
121
+ return 1
122
+ rows = [
123
+ ["n", str(len(data))],
124
+ ["mean", f"{mean(data):.6g}"],
125
+ ["median", f"{median(data):.6g}"],
126
+ ["min", f"{min(data):.6g}"],
127
+ ["max", f"{max(data):.6g}"],
128
+ ["p25", f"{percentile(data, 25):.6g}"],
129
+ ["p75", f"{percentile(data, 75):.6g}"],
130
+ ]
131
+ if len(data) > 1:
132
+ rows.append(["stdev", f"{stdev(data):.6g}"])
133
+ rows.append(["variance", f"{variance(data):.6g}"])
134
+ _print(_format_table("Descriptive stats", ["stat", "value"], rows))
135
+ return 0
136
+
137
+
138
+ def _cmd_integrate(args: argparse.Namespace) -> int:
139
+ """Numerical integration of a built-in integrand over [a, b]."""
140
+ import math
141
+
142
+ from cds.numerical_integration import simpson, trapezoid
143
+
144
+ integrands: dict[str, Callable[[float], float]] = {
145
+ "sin": math.sin,
146
+ "cos": math.cos,
147
+ "exp": math.exp,
148
+ "x2": lambda x: x * x,
149
+ "unit": lambda _x: 1.0,
150
+ }
151
+ name = args.integrand
152
+ if name not in integrands: # pragma: no cover - argparse choices
153
+ _print(
154
+ _render(
155
+ f"[red]Error:[/] unknown integrand {name!r}. "
156
+ f"Options: {', '.join(sorted(integrands))}"
157
+ )
158
+ )
159
+ return 1
160
+ f = integrands[name]
161
+ a, b, n = args.a, args.b, args.n
162
+ try:
163
+ if args.method == "trap":
164
+ result = trapezoid(f, a, b, n=n)
165
+ else:
166
+ result = simpson(f, a, b, n=n)
167
+ except ValueError as exc:
168
+ _print(_render(f"[red]Error:[/] {exc}"))
169
+ return 1
170
+ _print(_render(f"[green]∫_{a}^{b} {name}(x) dx ≈ {result:.10g}[/] ({args.method}, n={n})"))
171
+ return 0
172
+
173
+
174
+ def _cmd_sample(args: argparse.Namespace) -> int:
175
+ """Draw samples from a built-in probability distribution."""
176
+ from cds.probability import (
177
+ exponential_sample,
178
+ gaussian_sample,
179
+ poisson_sample,
180
+ uniform_sample,
181
+ )
182
+
183
+ n = args.n
184
+ seed = args.seed
185
+ dist = args.dist
186
+ try:
187
+ if dist == "uniform":
188
+ samples_f = uniform_sample(args.a, args.b, n, seed=seed)
189
+ text = ", ".join(f"{v:.6g}" for v in samples_f)
190
+ elif dist == "gaussian":
191
+ samples_f = gaussian_sample(n, mu=args.mu, sigma=args.sigma, seed=seed)
192
+ text = ", ".join(f"{v:.6g}" for v in samples_f)
193
+ elif dist == "exponential":
194
+ samples_f = exponential_sample(n, lam=args.lam, seed=seed)
195
+ text = ", ".join(f"{v:.6g}" for v in samples_f)
196
+ elif dist == "poisson":
197
+ samples_i = poisson_sample(n, lam=args.lam, seed=seed)
198
+ text = ", ".join(str(v) for v in samples_i)
199
+ else: # pragma: no cover - argparse choices reject unknown dist
200
+ _print(_render(f"[red]Error:[/] unknown dist {dist!r}"))
201
+ return 1
202
+ except ValueError as exc:
203
+ _print(_render(f"[red]Error:[/] {exc}"))
204
+ return 1
205
+ _print(text)
206
+ return 0
207
+
208
+
209
+ def _cmd_dashboard(args: argparse.Namespace) -> int:
210
+ """Launch the interactive System dashboard."""
211
+ root_dir = Path(__file__).parent.parent.parent.parent
212
+ dashboard_path = root_dir / "dashboard" / "app.py"
213
+ if not dashboard_path.exists():
214
+ _print(_render("[red]Error:[/] Dashboard file not found at " + str(dashboard_path)))
215
+ return 1
216
+
217
+ _print(_render("[yellow]Launching System Interactive Dashboard...[/]"))
218
+
219
+ # Ensure src is in PYTHONPATH so dashboard can import cds
220
+ env = os.environ.copy()
221
+ src_path = str(root_dir / "src")
222
+ if "PYTHONPATH" in env:
223
+ env["PYTHONPATH"] = f"{src_path}{os.pathsep}{env['PYTHONPATH']}"
224
+ else:
225
+ env["PYTHONPATH"] = src_path
226
+
227
+ try:
228
+ subprocess.run(
229
+ [sys.executable, "-m", "streamlit", "run", str(dashboard_path)],
230
+ check=True,
231
+ env=env,
232
+ )
233
+ except KeyboardInterrupt:
234
+ _print(_render("\n[blue]Dashboard stopped.[/]"))
235
+ except FileNotFoundError:
236
+ _print(
237
+ _render("[red]Error:[/] Streamlit not found. Install it with 'pip install streamlit'.")
238
+ )
239
+ return 1
240
+ return 0
241
+
242
+
243
+ def _cmd_benchmark(args: argparse.Namespace) -> int:
244
+ """Run built-in benchmarks to verify performance."""
245
+ _print(_render("[yellow]Benchmarking System performance...[/]"))
246
+ _print("Run 'python benchmarks/run_benchmarks.py' for detailed results.")
247
+ return 0
248
+
249
+
250
+ def _cmd_constants(args: argparse.Namespace) -> int:
251
+ """List available physical constants."""
252
+ from cds.scientific.constants import CONSTANTS
253
+
254
+ rows = [
255
+ [name, f"{val:.6e}" if val < 0.01 or val > 1e4 else f"{val}", desc]
256
+ for name, (val, desc) in CONSTANTS.items()
257
+ ]
258
+ _print(_format_table("Physical Constants", ["Name", "Value", "Description"], rows))
259
+ return 0
260
+
261
+
262
+ def _cmd_plot(args: argparse.Namespace) -> int:
263
+ """Plot a series of numbers (ASCII in terminal, or PNG via optional matplotlib)."""
264
+ try:
265
+ data = [float(x.strip()) for x in args.values.split(",")]
266
+ except ValueError:
267
+ _print(_render("[red]Error:[/] Values must be a comma-separated list of numbers."))
268
+ return 1
269
+
270
+ kind = getattr(args, "kind", "series") or "series"
271
+ out_file = getattr(args, "file", None)
272
+ if out_file:
273
+ # Optional matplotlib path — requires `pip install scientific-computing-system[plot]`.
274
+ try:
275
+ from cds.plot import plot_acf, plot_histogram, plot_series, save_figure
276
+ except ImportError as exc: # pragma: no cover - package always ships cds.plot
277
+ _print(_render(f"[red]Error:[/] {exc}"))
278
+ return 1
279
+ try:
280
+ if kind == "hist":
281
+ fig = plot_histogram(data, title=args.title)
282
+ elif kind == "acf":
283
+ fig = plot_acf(data, title=args.title)
284
+ elif kind == "series":
285
+ fig = plot_series(data, title=args.title)
286
+ else: # pragma: no cover - argparse choices reject unknown kind
287
+ _print(
288
+ _render(f"[red]Error:[/] Unknown --kind {kind!r}. Options: series, hist, acf")
289
+ )
290
+ return 1
291
+ save_figure(fig, out_file)
292
+ except ImportError as exc:
293
+ _print(_render(f"[red]Error:[/] {exc}"))
294
+ return 1
295
+ except ValueError as exc:
296
+ _print(_render(f"[red]Error:[/] {exc}"))
297
+ return 1
298
+ _print(_render(f"[green]Saved[/] {out_file} ({kind})"))
299
+ return 0
300
+
301
+ if kind != "series":
302
+ _print(
303
+ _render(
304
+ "[red]Error:[/] ASCII mode only supports --kind series "
305
+ "(use --file with cds[plot] for hist/acf)."
306
+ )
307
+ )
308
+ return 1
309
+
310
+ from cds.data_analysis.viz import plot_line
311
+
312
+ _print(plot_line(data, title=args.title))
313
+ return 0
314
+
315
+
316
+ def _cmd_calc(args: argparse.Namespace) -> int:
317
+ """Quick physics calculations."""
318
+ from cds.scientific import formulas
319
+
320
+ try:
321
+ if args.formula == "ke":
322
+ _print("KE = 0.5 * m * v²")
323
+ m = float(input("mass (kg) "))
324
+ v = float(input("velocity (m/s) "))
325
+ _print(_render(f"[green]Kinetic Energy = {formulas.kinetic_energy(m, v):.4f} J[/]"))
326
+ elif args.formula == "gravity":
327
+ _print("F = G * m1 * m2 / r²")
328
+ m1 = float(input("mass 1 (kg) "))
329
+ m2 = float(input("mass 2 (kg) "))
330
+ r = float(input("distance (m) "))
331
+ _print(_render(f"[green]Force = {formulas.gravitational_force(m1, m2, r):.6e} N[/]"))
332
+ elif args.formula == "wave":
333
+ wl = float(input("wavelength (m) "))
334
+ _print(_render(f"[green]Frequency = {formulas.wave_frequency(wl):.4e} Hz[/]"))
335
+ elif args.formula == "gas":
336
+ n = float(input("moles "))
337
+ t = float(input("temperature (K) "))
338
+ v = float(input("volume (m³) "))
339
+ _print(_render(f"[green]Pressure = {formulas.ideal_gas_pressure(n, t, v):.2f} Pa[/]"))
340
+ else:
341
+ _print(
342
+ _render(
343
+ f"[red]Unknown formula '{args.formula}'. Options: ke, gravity, wave, gas[/]"
344
+ )
345
+ )
346
+ except ValueError:
347
+ _print(_render("[red]Error:[/] Input must be a valid number."))
348
+ return 1
349
+ except Exception as e: # noqa: BLE001 — CLI surface, keep the message readable
350
+ _print(_render(f"[red]Error:[/] {str(e)}"))
351
+ return 1
352
+ return 0
353
+
354
+
355
+ def _cmd_modules(args: argparse.Namespace) -> int:
356
+ """List all scientific modules available in the System."""
357
+ module_info = [
358
+ ("cds.quantum", "Single & multi-qubit circuits, Bell/GHZ states, entanglement"),
359
+ ("cds.signals", "DFT, radix-2 FFT, 2D FFT, convolution, filtering"),
360
+ ("cds.math_utils", "LU/QR/Cholesky, power iteration, Gram-Schmidt, calculus"),
361
+ (
362
+ "cds.optimization",
363
+ "Gradient descent, Newton, Adam, golden section, Nelder-Mead, simulated annealing",
364
+ ),
365
+ (
366
+ "cds.stats",
367
+ "Descriptive stats, regression, t-tests, ANOVA, time-series, Mann-Whitney U, Wilcoxon",
368
+ ),
369
+ (
370
+ "cds.probability",
371
+ "Gaussian/binomial/Poisson plus chi-square/t quantiles, gamma/beta samplers",
372
+ ),
373
+ ("cds.montecarlo", "π estimation, integration, random walks"),
374
+ (
375
+ "cds.diffeq",
376
+ "Euler, RK4, RK45 + implicit stiff solvers (backward Euler, Crank-Nicolson)",
377
+ ),
378
+ ("cds.graph", "BFS/DFS, Dijkstra, Kruskal MST, topological sort"),
379
+ (
380
+ "cds.modeling",
381
+ "Symbolic math: expressions, MathModel, equation solving, parameter fitting",
382
+ ),
383
+ ("cds.knowledge", "Knowledge graph, concept mapping, research notes, structured retrieval"),
384
+ ("cds.ml", "MLP, k-NN, k-means, decision tree, logistic/linear regression, PCA, scaler"),
385
+ ("cds.scientific", "Physical constants + common formulas"),
386
+ ("cds.data_analysis", "CSV loading, normalization, z-score, moving average"),
387
+ ("cds.nlp", "Educational NLP: BPE tokenizer, embeddings, attention, autograd, MiniGPT"),
388
+ (
389
+ "cds.hypothesis",
390
+ "Structured hypothesis generation with prompt templates for custom research workflows",
391
+ ),
392
+ (
393
+ "cds.plot",
394
+ "Optional matplotlib charts (series, spectrum, ACF/PACF, optimizer paths) — pip install cds[plot]",
395
+ ),
396
+ (
397
+ "cds.numerical_integration",
398
+ "Trapezoid, Simpson, Romberg, Gauss-Legendre, adaptive + 2-D quadrature",
399
+ ),
400
+ ]
401
+ rows = [[name, desc] for name, desc in module_info]
402
+ _print(_format_table("System Scientific Modules", ["Module", "Key Capabilities"], rows))
403
+ _print(_render("\n[dim]All modules are pure Python with no heavy dependencies.[/]"))
404
+ _print(_render("[dim]See examples/ for runnable demos of each module.[/]\n"))
405
+ return 0