pydasa 0.4.7__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 (58) hide show
  1. pydasa/__init__.py +103 -0
  2. pydasa/_version.py +6 -0
  3. pydasa/analysis/__init__.py +0 -0
  4. pydasa/analysis/scenario.py +584 -0
  5. pydasa/analysis/simulation.py +1158 -0
  6. pydasa/context/__init__.py +0 -0
  7. pydasa/context/conversion.py +11 -0
  8. pydasa/context/system.py +17 -0
  9. pydasa/context/units.py +15 -0
  10. pydasa/core/__init__.py +15 -0
  11. pydasa/core/basic.py +287 -0
  12. pydasa/core/cfg/default.json +136 -0
  13. pydasa/core/constants.py +27 -0
  14. pydasa/core/io.py +102 -0
  15. pydasa/core/setup.py +269 -0
  16. pydasa/dimensional/__init__.py +0 -0
  17. pydasa/dimensional/buckingham.py +728 -0
  18. pydasa/dimensional/fundamental.py +146 -0
  19. pydasa/dimensional/model.py +1077 -0
  20. pydasa/dimensional/vaschy.py +633 -0
  21. pydasa/elements/__init__.py +19 -0
  22. pydasa/elements/parameter.py +218 -0
  23. pydasa/elements/specs/__init__.py +22 -0
  24. pydasa/elements/specs/conceptual.py +161 -0
  25. pydasa/elements/specs/numerical.py +469 -0
  26. pydasa/elements/specs/statistical.py +229 -0
  27. pydasa/elements/specs/symbolic.py +394 -0
  28. pydasa/serialization/__init__.py +27 -0
  29. pydasa/serialization/parser.py +133 -0
  30. pydasa/structs/__init__.py +0 -0
  31. pydasa/structs/lists/__init__.py +0 -0
  32. pydasa/structs/lists/arlt.py +578 -0
  33. pydasa/structs/lists/dllt.py +18 -0
  34. pydasa/structs/lists/ndlt.py +262 -0
  35. pydasa/structs/lists/sllt.py +746 -0
  36. pydasa/structs/tables/__init__.py +0 -0
  37. pydasa/structs/tables/htme.py +182 -0
  38. pydasa/structs/tables/scht.py +774 -0
  39. pydasa/structs/tools/__init__.py +0 -0
  40. pydasa/structs/tools/hashing.py +53 -0
  41. pydasa/structs/tools/math.py +149 -0
  42. pydasa/structs/tools/memory.py +54 -0
  43. pydasa/structs/types/__init__.py +0 -0
  44. pydasa/structs/types/functions.py +131 -0
  45. pydasa/structs/types/generics.py +54 -0
  46. pydasa/validations/__init__.py +0 -0
  47. pydasa/validations/decorators.py +510 -0
  48. pydasa/validations/error.py +100 -0
  49. pydasa/validations/patterns.py +32 -0
  50. pydasa/workflows/__init__.py +1 -0
  51. pydasa/workflows/influence.py +497 -0
  52. pydasa/workflows/phenomena.py +529 -0
  53. pydasa/workflows/practical.py +765 -0
  54. pydasa-0.4.7.dist-info/METADATA +320 -0
  55. pydasa-0.4.7.dist-info/RECORD +58 -0
  56. pydasa-0.4.7.dist-info/WHEEL +5 -0
  57. pydasa-0.4.7.dist-info/licenses/LICENSE +674 -0
  58. pydasa-0.4.7.dist-info/top_level.txt +1 -0
@@ -0,0 +1,218 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Module parameter.py
4
+ ===========================================
5
+
6
+ Module for representing **Variable** entities in Dimensional Analysis for *PyDASA*.
7
+
8
+ Classes:
9
+ **Variable**: Represents a Variable with dimensional properties, value ranges, and validation.
10
+
11
+ *IMPORTANT:* Based on the theory from:
12
+
13
+ # H.Gorter, *Dimensionalanalyse: Eine Theoririe der physikalischen Dimensionen mit Anwendungen*
14
+ """
15
+
16
+ # native python modules
17
+ # dataclass imports
18
+ from __future__ import annotations
19
+ from dataclasses import dataclass, fields
20
+ # data type imports
21
+ from typing import Dict, Any
22
+ # numerical imports
23
+ import numpy as np
24
+
25
+ # custom modules
26
+ # Import the four compositional perspectives
27
+ from pydasa.elements.specs import ConceptualSpecs
28
+ from pydasa.elements.specs import SymbolicSpecs
29
+ from pydasa.elements.specs import NumericalSpecs
30
+ from pydasa.elements.specs import StatisticalSpecs
31
+ # pattern interpreter imports
32
+ from pydasa.serialization.parser import latex_to_python
33
+
34
+
35
+ @dataclass
36
+ class Variable(ConceptualSpecs, SymbolicSpecs, NumericalSpecs, StatisticalSpecs):
37
+ """**Variable** class for Dimensional Analysis in *PyDASA*.
38
+
39
+ A comprehensive implementation that combines Parameter and Variable functionality
40
+ for use in dimensional analysis calculations, simulations, and sensitivity analysis.
41
+
42
+ This class composes four philosophical perspectives through multiple inheritance:
43
+ - **ConceptualSpecs**: Identity and classification (what IS this variable?)
44
+ - **SymbolicSpecs**: Mathematical representation (how do we WRITE it?)
45
+ - **NumericalSpecs**: Computational values (what VALUES can it take?)
46
+ - **StatisticalSpecs**: Probabilistic modeling (how do we MODEL uncertainty?)
47
+
48
+ All attributes, properties, and methods are inherited from the spec classes.
49
+ This class only provides integration logic and utility methods.
50
+
51
+ Attributes:
52
+ # From Foundation (via ConceptualSpecs)
53
+ _name (str): User-friendly name of the variable.
54
+ description (str): Brief summary of the variable.
55
+ _idx (int): Index/precedence in the dimensional matrix.
56
+ _sym (str): Symbol representation (LaTeX or alphanumeric).
57
+ _alias (str): Python-compatible alias for use in code.
58
+ _fwk (str): Frameworks context (PHYSICAL, COMPUTATION, SOFTWARE, CUSTOM).
59
+
60
+ # From ConceptualSpecs - Identity and Classification
61
+ _cat (str): Category (INPUT, OUT, CTRL).
62
+ _schema (Schema): Reference to the dimensional framework or FDUs list.
63
+ relevant (bool): Flag indicating if variable is relevant for analysis.
64
+
65
+ # From SymbolicSpecs - Dimensional Properties
66
+ _dims (str): Dimensional expression (e.g., "L*T^-1").
67
+ _units (str): Units of measure (e.g., "m/s").
68
+ _sym_exp (str): Sympy-compatible expression.
69
+ _dim_col (List[int]): Dimensional column for matrix operations.
70
+
71
+ # From SymbolicSpecs - Standardized Dimensional Properties
72
+ _std_dims (str): Standardized dimensional expression.
73
+ _std_units (str): Standardized units of measure.
74
+
75
+ # From NumericalSpecs - Value Ranges (Original Units)
76
+ _min (float): Minimum value in original units.
77
+ _max (float): Maximum value in original units.
78
+ _mean (float): Mean value in original units.
79
+ _dev (float): Standard deviation in original units.
80
+
81
+ # From NumericalSpecs - Value Ranges (Standardized Units)
82
+ _std_min (float): Minimum value in standard units.
83
+ _std_max (float): Maximum value in standard units.
84
+ _std_mean (float): Mean value in standard units.
85
+ _std_dev (float): Standard deviation in standard units.
86
+ _step (float): Step size for simulations.
87
+ _std_range (np.ndarray): Range array for analysis.
88
+
89
+ # From StatisticalSpecs - Distribution Specifications
90
+ _dist_type (str): Type of distribution (e.g., 'uniform', 'normal').
91
+ _dist_params (Dict[str, Any]): Parameters for the distribution.
92
+ _depends (List[str]): List of variable names that this variable depends on.
93
+ _dist_func (Callable): Callable representing the distribution function.
94
+ """
95
+
96
+ def __post_init__(self) -> None:
97
+ """*__post_init__()* Initializes the variable and validates its properties.
98
+
99
+ Performs validation of core properties and processes dimensional expressions.
100
+ Sets up range arrays if all required values are provided.
101
+
102
+ Raises:
103
+ ValueError: If dimensional expression is invalid.
104
+ """
105
+ # Initialize from base class (ConceptualSpecs -> Foundation)
106
+ # This also sets up the schema based on framework
107
+ super().__post_init__()
108
+
109
+ if not self._sym:
110
+ self._sym = f"V_{self._idx}" if self._idx >= 0 else "V_{}"
111
+
112
+ # if custom schema is provided and dimensions exist
113
+ if self._schema and len(self._dims) > 0 and self._dims != "n.a.":
114
+ # if not self._schema.validate_dims(self._dims):
115
+ # raise ValueError(f"Invalid dimensions for {self._fwk}")
116
+ # # Process dimensions if provided
117
+ # if len(self._dims) > 0 and self._dims != "n.a.":
118
+ _schema = self._schema
119
+ if not self._validate_exp(self._dims, _schema.fdu_regex):
120
+ _msg = f"Invalid dimensions {self._dims} for '{self._sym}'."
121
+ _msg += f"Check FDU precedence list: {_schema.fdu_lt}."
122
+ raise ValueError(_msg)
123
+ self._prepare_dims()
124
+
125
+ # Set the Python alias if not specified
126
+ if not self._alias:
127
+ self._alias = latex_to_python(self._sym)
128
+
129
+ # TODO reassert this code later, seems redundant
130
+ # Set up range array if all required values are provided
131
+ if all([self._std_min, self._std_max, self._step]):
132
+ self._std_range = np.arange(self._std_min,
133
+ self._std_max,
134
+ self._step)
135
+
136
+ # NOTE: All methods below are inherited from spec classes:
137
+ # - All properties (cat, dims, units, min, max, etc.) are inherited from respective specs
138
+
139
+ def clear(self) -> None:
140
+ """*clear()* Reset all attributes to default values.
141
+
142
+ Resets all variable properties to their initial state by calling
143
+ clear() on all composed perspective classes.
144
+ """
145
+ # Call clear on all parent classes
146
+ ConceptualSpecs.clear(self)
147
+ SymbolicSpecs.clear(self)
148
+ NumericalSpecs.clear(self)
149
+ StatisticalSpecs.clear(self)
150
+
151
+ def to_dict(self) -> Dict[str, Any]:
152
+ """*to_dict()* Convert variable to dictionary representation.
153
+
154
+ Returns:
155
+ Dict[str, Any]: Dictionary representation of variable.
156
+ """
157
+ result = {}
158
+
159
+ # Get all dataclass fields
160
+ for f in fields(self):
161
+ attr_name = f.name
162
+ attr_value = getattr(self, attr_name)
163
+
164
+ # Skip numpy arrays (not JSON serializable without special handling)
165
+ if isinstance(attr_value, np.ndarray):
166
+ # Convert to list for JSON compatibility
167
+ attr_value = attr_value.tolist()
168
+
169
+ # Skip callables (can't be serialized)
170
+ if callable(attr_value) and attr_name == "_dist_func":
171
+ continue
172
+
173
+ # Remove leading underscore from private attributes
174
+ if attr_name.startswith("_"):
175
+ clean_name = attr_name[1:] # Remove first character
176
+ else:
177
+ clean_name = attr_name
178
+
179
+ result[clean_name] = attr_value
180
+
181
+ return result
182
+
183
+ @classmethod
184
+ def from_dict(cls, data: Dict[str, Any]) -> Variable:
185
+ """*from_dict()* Create variable from dictionary representation.
186
+
187
+ Args:
188
+ data (Dict[str, Any]): Dictionary representation of variable.
189
+
190
+ Returns:
191
+ Variable: New variable instance.
192
+ """
193
+ # Get all valid field names from the dataclass
194
+ field_names = {f.name for f in fields(cls)}
195
+
196
+ # Map keys without underscores to keys with underscores
197
+ mapped_data = {}
198
+
199
+ for key, value in data.items():
200
+ # Try the key as-is first (handles both _idx and name)
201
+ if key in field_names:
202
+ mapped_data[key] = value
203
+ # Try adding underscore prefix (handles idx -> _idx)
204
+ elif f"_{key}" in field_names:
205
+ mapped_data[f"_{key}"] = value
206
+ # Try removing underscore prefix (handles _name -> name if needed)
207
+ elif key.startswith("_") and key[1:] in field_names:
208
+ mapped_data[key[1:]] = value
209
+ else:
210
+ # Use as-is for unknown keys (will be validated by dataclass)
211
+ mapped_data[key] = value
212
+
213
+ # Convert lists back to numpy arrays for range attributes
214
+ for range_key in ["std_range", "_std_range"]:
215
+ if range_key in mapped_data and isinstance(mapped_data[range_key], list):
216
+ mapped_data[range_key] = np.array(mapped_data[range_key])
217
+
218
+ return cls(**mapped_data)
@@ -0,0 +1,22 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Variable specifications module.
4
+
5
+ Four compositional perspectives for variable representation:
6
+ - ConceptualSpecs: Identity and classification
7
+ - SymbolicSpecs: Mathematical notation and dimensions
8
+ - NumericalSpecs: Computational values and ranges
9
+ - StatisticalSpecs: Probabilistic distributions
10
+ """
11
+
12
+ from .conceptual import ConceptualSpecs
13
+ from .symbolic import SymbolicSpecs
14
+ from .numerical import NumericalSpecs
15
+ from .statistical import StatisticalSpecs
16
+
17
+ __all__ = [
18
+ 'ConceptualSpecs',
19
+ 'SymbolicSpecs',
20
+ 'NumericalSpecs',
21
+ 'StatisticalSpecs',
22
+ ]
@@ -0,0 +1,161 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Module conceptual.py
4
+ ===========================================
5
+
6
+ Conceptual perspective for variable representation.
7
+
8
+ This module defines the ConceptualSpecs class representing the abstract
9
+ identity and classification of a variable.
10
+
11
+ Classes:
12
+ **ConceptualSpecs**: Conceptual variable specifications
13
+
14
+ *IMPORTANT:* Based on the theory from:
15
+
16
+ # H.Gorter, *Dimensionalanalyse: Eine Theoririe der physikalischen Dimensionen mit Anwendungen*
17
+ """
18
+
19
+ # native python modules
20
+ # dataclass imports
21
+ from __future__ import annotations
22
+ from dataclasses import dataclass
23
+ from typing import Optional, List
24
+
25
+ # custom modules
26
+ from pydasa.core.basic import Foundation
27
+ from pydasa.dimensional.vaschy import Schema
28
+ from pydasa.core.setup import Frameworks
29
+ from pydasa.core.setup import VarCardinality
30
+ from pydasa.core.setup import PYDASA_CFG
31
+ from pydasa.validations.decorators import validate_choices
32
+
33
+
34
+ @dataclass
35
+ class ConceptualSpecs(Foundation):
36
+ """Conceptual perspective: variable identity and classification.
37
+
38
+ Answers the fundamental question: "What IS this variable?". This perspective focuses on:
39
+ - What category does it belong to? (INPUT, OUTPUT, CONTROL)
40
+ - Which framework is it part of? (PHYSICAL, COMPUTATION, SOFTWARE, CUSTOM)
41
+ - Is it relevant for the current analysis?
42
+ - What dimensional framework does it use?
43
+
44
+ Attributes:
45
+ # From Foundation
46
+ _name (str): User-friendly name of the variable.
47
+ description (str): Brief summary of the variable.
48
+ _idx (int): Index/precedence in the dimensional matrix.
49
+ _sym (str): Symbol representation (LaTeX or alphanumeric).
50
+ _alias (str): Python-compatible alias for use in code.
51
+ _fwk (str): Frameworks context (PHYSICAL, COMPUTATION, SOFTWARE, CUSTOM).
52
+ # From ConceptualSpecs
53
+ _schema (Optional[Schema]): Reference to the dimensional framework schema.
54
+ _cat (str): Category of the variable (INPUT, OUTPUT, CONTROL).
55
+ relevant (bool): Flag indicating if variable is relevant for analysis.
56
+ """
57
+
58
+ # Private attributes
59
+ # :attr: _schema
60
+ _schema: Optional[Schema] = None
61
+ """Reference to the dimensional framework schema."""
62
+
63
+ # Category attribute (INPUT, OUT, CTRL)
64
+ # :attr: _cat
65
+ _cat: str = VarCardinality.IN.value
66
+ """Category of the variable (INPUT, OUT, CTRL)."""
67
+
68
+ # Flags
69
+ # :attr: relevant
70
+ relevant: bool = False
71
+ """Flag indicating if variable is relevant for analysis."""
72
+
73
+ def __post_init__(self) -> None:
74
+ """*__post_init__()* Initializes the conceptual properties.
75
+
76
+ Sets up the schema reference based on framework if not explicitly provided.
77
+
78
+ Raises:
79
+ ValueError: If framework configuration is invalid.
80
+ """
81
+ # Initialize from base class
82
+ super().__post_init__()
83
+
84
+ # If no schema provided, create default or use global
85
+ if self._schema is None and self._fwk != Frameworks.CUSTOM.value:
86
+ self._schema = Schema(_fwk=self._fwk)
87
+
88
+ def _validate_in_list(self, value: str, prec_lt: List[str]) -> bool:
89
+ """*_validate_in_list()* Validates if a value exists in a list of allowed values.
90
+
91
+ Args:
92
+ value (str): Value to validate.
93
+ prec_lt (List[str]): List of allowed values.
94
+
95
+ Returns:
96
+ bool: True if the value is in the list, False otherwise.
97
+ """
98
+ if value in [None, ""]:
99
+ return False
100
+ return value in prec_lt
101
+
102
+ # Property getters and setters
103
+ # Identification and Classification
104
+
105
+ @property
106
+ def cat(self) -> str:
107
+ """*cat* Get the category of the variable.
108
+
109
+ Returns:
110
+ str: Category (INPUT, OUT, CTRL).
111
+ """
112
+ return self._cat
113
+
114
+ @cat.setter
115
+ @validate_choices(PYDASA_CFG.parameter_cardinality)
116
+ def cat(self, val: str) -> None:
117
+ """*cat* Set the category of the variable.
118
+
119
+ Args:
120
+ val (str): Category (INPUT, OUT, CTRL).
121
+
122
+ Raises:
123
+ ValueError: If category is invalid.
124
+ """
125
+ # if val.upper() not in PYDASA_CFG.parameter_cardinality:
126
+ # _msg = f"Invalid category: {val}. "
127
+ # _msg += "Category must be one of the following: "
128
+ # _msg += f"{', '.join(_param_keys)}."
129
+ # raise ValueError(_msg)
130
+ self._cat = val.upper()
131
+
132
+ @property
133
+ def schema(self) -> Optional[Schema]:
134
+ """*schema* Get the dimensional schema reference.
135
+
136
+ Returns:
137
+ Optional[Schema]: The dimensional framework schema.
138
+ """
139
+ return self._schema
140
+
141
+ @schema.setter
142
+ def schema(self, val: Optional[Schema]) -> None:
143
+ """*schema* Set the dimensional schema reference.
144
+
145
+ Args:
146
+ val (Optional[Schema]): The dimensional framework schema.
147
+ """
148
+ self._schema = val
149
+
150
+ def clear(self) -> None:
151
+ """*clear()* Reset conceptual attributes to default values.
152
+
153
+ Resets category, schema, and relevance flag.
154
+ """
155
+ # Reset base class attributes
156
+ super().clear()
157
+
158
+ # Reset variable-specific attributes
159
+ self._cat = VarCardinality.IN.value
160
+ self._schema = None
161
+ self.relevant = False