daehn 2.0.0__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.
daehn/__init__.py ADDED
@@ -0,0 +1,28 @@
1
+ """Differential hard-constrained learning through OHAGI and PURIN."""
2
+
3
+ import sys as _sys
4
+ from importlib import import_module as _module
5
+ from .api.root import * # noqa: F403 - compatibility facade mirrors upstream exports
6
+ from .api.root import __all__ as __all__, __version__ as __version__
7
+
8
+ # Current public benchmark paths point directly to their implementations.
9
+ # No legacy implementation tree or import hook is installed.
10
+ for _name, _target in {
11
+ "dae": "daehn.api.differential",
12
+ "dae.model": "daehn.api.differential.reconstruction",
13
+ "dae.conditions": "daehn.api.differential.conditions",
14
+ "dae.discretization": "daehn.api.differential.discretization",
15
+ "opt": "daehn.api.projection",
16
+ "opt.layers": "daehn.api.projection",
17
+ "opt.layers.projection": "daehn.api.projection",
18
+ "train": "ohagi.training",
19
+ "train.projected_neural": "daehn.api.root",
20
+ "train.steps": "ohagi.training.steps",
21
+ "nn": "daehn.api.network",
22
+ "problems": "daehn.api.problem",
23
+ "losses": "ohagi.losses",
24
+ "runtime": "ohagi.execution.runtime",
25
+ "tree": "ohagi._utils.tree",
26
+ }.items():
27
+ _sys.modules[__name__ + "." + _name] = _module(_target)
28
+ del _name, _target
daehn/api/__init__.py ADDED
@@ -0,0 +1,49 @@
1
+ """Problem-specific DAEHN adapters to OHAGI and PURIN."""
2
+
3
+ from importlib import import_module
4
+
5
+ __all__ = [
6
+ "nn",
7
+ "opt",
8
+ "problems",
9
+ "dae",
10
+ "train",
11
+ "losses",
12
+ "runtime",
13
+ "tree",
14
+ "Problem",
15
+ "SymbolicProblem",
16
+ "FunctionalProblem",
17
+ "MatrixProblem",
18
+ "ParametricLP",
19
+ "ParametricQP",
20
+ "ProjectionConfig",
21
+ "LinearSolverConfig",
22
+ "ImplicitGradientConfig",
23
+ "DAEHardNet",
24
+ "ProjectedNeuralModel",
25
+ "MLPBackbone",
26
+ "FlaxMLPBackbone",
27
+ "Adam",
28
+ "AdamState",
29
+ "BuildReport",
30
+ "PredictionOutput",
31
+ "ProjectedMetrics",
32
+ "CompiledProjectedGraphs",
33
+ "ProjectionLayerOutput",
34
+ "ImplicitProjectionLayer",
35
+ "make_implicit_projection_layer",
36
+ "apply_updates",
37
+ "configure_compilation_cache",
38
+ "save_predictor",
39
+ "load_predictor",
40
+ ]
41
+
42
+
43
+ def __getattr__(name):
44
+ if name not in __all__ and name != "__version__":
45
+ raise AttributeError(name)
46
+ root = import_module("daehn.api.root")
47
+ if name in root.__all__ or name == "__version__":
48
+ return getattr(root, name)
49
+ raise AttributeError(name)
@@ -0,0 +1,20 @@
1
+ """DAEHN defaults for the common PURIN solver configuration."""
2
+
3
+ from dataclasses import dataclass, field
4
+ from purin.solvers.config import ImplicitGradientConfig as ImplicitGradientConfig
5
+ from purin.solvers.config import LinearSolverConfig as _Linear
6
+ from purin.solvers.config import ProjectionConfig as _Projection
7
+
8
+
9
+ @dataclass(frozen=True)
10
+ class LinearSolverConfig(_Linear):
11
+ """DAE frontend defaults for PURIN's linear-system solver configuration."""
12
+
13
+ max_iterations: int = 50
14
+
15
+
16
+ @dataclass(frozen=True)
17
+ class ProjectionConfig(_Projection):
18
+ """DAE frontend defaults for projection tolerance, iteration and gradient policy."""
19
+
20
+ linear_solver: _Linear = field(default_factory=LinearSolverConfig)
daehn/api/data.py ADDED
@@ -0,0 +1,83 @@
1
+ """Deterministic array datasets for DAE training, conditions, and examples."""
2
+
3
+ from __future__ import annotations
4
+ from dataclasses import dataclass
5
+ from pathlib import Path
6
+ import numpy as np
7
+
8
+
9
+ @dataclass(frozen=True)
10
+ class DAEData:
11
+ """Observation arrays and optional derivative/condition supervision for a DAE.
12
+
13
+ Attributes:
14
+ coordinates: Coordinate observations with a leading sample dimension.
15
+ parameters: Physical parameter observations aligned with coordinates.
16
+ states: Observed differential and algebraic state values.
17
+ derivatives: Optional derivative targets in the compiled derivative order.
18
+ initial_coordinates: Optional points for initial-condition supervision.
19
+ initial_targets: Optional state targets at those initial points.
20
+ boundary_coordinates: Optional points for boundary-condition supervision.
21
+ boundary_targets: Optional state targets at those boundary points.
22
+ initial_mask: Optional mask selecting initial-condition observations.
23
+ boundary_mask: Optional mask selecting boundary-condition observations.
24
+
25
+ Notes:
26
+ ``save`` and ``load`` preserve optional fields through the NPZ dataset
27
+ format. These datasets are separate from model inference artifacts.
28
+ """
29
+
30
+ coordinates: np.ndarray
31
+ parameters: np.ndarray
32
+ states: np.ndarray
33
+ derivatives: np.ndarray | None = None
34
+ initial_coordinates: np.ndarray | None = None
35
+ initial_targets: np.ndarray | None = None
36
+ boundary_coordinates: np.ndarray | None = None
37
+ boundary_targets: np.ndarray | None = None
38
+ initial_mask: np.ndarray | None = None
39
+ boundary_mask: np.ndarray | None = None
40
+
41
+ def save(self, path):
42
+ """Save observation arrays to NPZ, encoding absent optional fields as empty arrays."""
43
+ path = Path(path)
44
+ path.parent.mkdir(parents=True, exist_ok=True)
45
+
46
+ def value(x):
47
+ return np.asarray([]) if x is None else np.asarray(x)
48
+
49
+ np.savez(
50
+ path,
51
+ coordinates=self.coordinates,
52
+ parameters=self.parameters,
53
+ states=self.states,
54
+ derivatives=value(self.derivatives),
55
+ initial_coordinates=value(self.initial_coordinates),
56
+ initial_targets=value(self.initial_targets),
57
+ boundary_coordinates=value(self.boundary_coordinates),
58
+ boundary_targets=value(self.boundary_targets),
59
+ initial_mask=value(self.initial_mask),
60
+ boundary_mask=value(self.boundary_mask),
61
+ )
62
+
63
+ @classmethod
64
+ def load(cls, path):
65
+ """Restore NPZ observations and decode empty optional fields as None."""
66
+ data = np.load(path)
67
+
68
+ def optional(name):
69
+ value = data[name]
70
+ return None if value.size == 0 else value
71
+
72
+ return cls(
73
+ data["coordinates"],
74
+ data["parameters"],
75
+ data["states"],
76
+ optional("derivatives"),
77
+ optional("initial_coordinates"),
78
+ optional("initial_targets"),
79
+ optional("boundary_coordinates"),
80
+ optional("boundary_targets"),
81
+ optional("initial_mask"),
82
+ optional("boundary_mask"),
83
+ )
@@ -0,0 +1,71 @@
1
+ """Continuous DAE formulation and discretization frontend for DAEHN."""
2
+
3
+ from daehn.api.differential.symbols import Coordinate
4
+ from daehn.api.differential.symbols import DifferentialState
5
+ from daehn.api.differential.symbols import AlgebraicState
6
+ from daehn.api.differential.symbols import Parameter
7
+ from daehn.api.differential.derivatives import DerivativeSpec
8
+ from daehn.api.differential.derivatives import derivative_closure
9
+ from daehn.api.differential.equations import EquationBlock
10
+ from daehn.api.differential.system import DAESystem
11
+ from daehn.api.differential.scaling import ScalingConfig
12
+ from daehn.api.differential.compiler import compile_dae
13
+ from daehn.api.differential.compiler import CompiledDAE
14
+ from daehn.api.differential.compiler import PreparedDAEProjection
15
+ from daehn.api.differential.reconstruction import FullModelDerivativePlan
16
+ from daehn.api.differential.reconstruction import ProjectedDAEModel
17
+ from daehn.api.differential.reconstruction import extract_network_derivatives
18
+ from daehn.api.data import DAEData
19
+ from daehn.api.fit import DAETrainer
20
+ from daehn.api.fit import DAETrainingConfig
21
+ from daehn.api.fit import DAETrainingResult
22
+ from daehn.api.logging import DAETrainingLogger
23
+ from daehn.api.objectives import physical_residual_blocks
24
+ from daehn.api.objectives import physical_violation_metrics
25
+ from daehn.api.objectives import dae_metrics
26
+ from daehn.api.differential.discretization import TaylorNeighborhood
27
+ from daehn.api.differential.discretization import ForwardDifference
28
+ from daehn.api.differential.discretization import CentralDifference
29
+ from daehn.api.differential.conditions import Condition
30
+ from daehn.api.differential.conditions import InitialCondition
31
+ from daehn.api.differential.conditions import BoundaryCondition
32
+ from daehn.api.differential.conditions import sample_condition_coordinates
33
+ from daehn.api.differential.conditions import condition_mse
34
+ from daehn.api.differential.conditions import hard_initial_transform
35
+ from daehn.api.differential.conditions import homogeneous_box_transform
36
+
37
+ __all__ = [
38
+ "Coordinate",
39
+ "DifferentialState",
40
+ "AlgebraicState",
41
+ "Parameter",
42
+ "DerivativeSpec",
43
+ "derivative_closure",
44
+ "EquationBlock",
45
+ "DAESystem",
46
+ "ScalingConfig",
47
+ "compile_dae",
48
+ "CompiledDAE",
49
+ "PreparedDAEProjection",
50
+ "FullModelDerivativePlan",
51
+ "ProjectedDAEModel",
52
+ "extract_network_derivatives",
53
+ "DAEData",
54
+ "DAETrainer",
55
+ "DAETrainingConfig",
56
+ "DAETrainingResult",
57
+ "DAETrainingLogger",
58
+ "physical_residual_blocks",
59
+ "physical_violation_metrics",
60
+ "dae_metrics",
61
+ "TaylorNeighborhood",
62
+ "ForwardDifference",
63
+ "CentralDifference",
64
+ "Condition",
65
+ "InitialCondition",
66
+ "BoundaryCondition",
67
+ "sample_condition_coordinates",
68
+ "condition_mse",
69
+ "hard_initial_transform",
70
+ "homogeneous_box_transform",
71
+ ]