Coverage for src/amisc/__init__.py: 100%

8 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2024-08-29 21:38 +0000

1"""Efficient framework for building surrogates of multidisciplinary systems using the adaptive multi-index stochastic 

2collocation (AMISC) technique. 

3 

4- Author - Joshua Eckels (eckelsjd@umich.edu) 

5- License - GPL-3.0 

6 

7The `amisc` package takes an object-oriented approach to building a surrogate of a multidisciplinary system. From the 

8bottom up, you have: 

9 

10- **variables** that serve as inputs and outputs for the models, 

11- **interpolators** that define a specific input → output mathematical relationship to interpolate a function, 

12- **components** that wrap a model for a single discipline, and a 

13- **system** that defines the connections between components in a multidisciplinary system. 

14 

15The variables, interpolators, and components all have abstract base classes, so that the **system** is ultimately 

16independent of the specific models, interpolation methods, or underlying variables. As such, the primary top-level 

17object that users of the `amisc` package will interact with is the `SystemSurrogate`. 

18 

19!!! Note 

20 There are already pretty good implementations of the other abstractions that most users will not need to worry 

21 about, but they are provided in this API reference for completeness. The abstractions allow new interpolation 

22 (i.e. function approximation) methods to be implemented if desired, such as neural networks, kriging, etc. 

23 

24Here is a class diagram summary of this workflow: 

25 

26``` mermaid 

27classDiagram 

28 namespace Core { 

29 class SystemSurrogate { 

30 +list[BaseRV] exo_vars 

31 +list[BaseRV] coupling_vars 

32 +int refine_level 

33 +fit() 

34 +predict(x) 

35 +sample_inputs(size) 

36 +insert_component(comp) 

37 } 

38 class ComponentSurrogate { 

39 <<abstract>> 

40 +IndexSet index_set 

41 +IndexSet candidate_set 

42 +list[BaseRV] x_vars 

43 +dict[str: BaseInterpolator] surrogates 

44 +dict[str: float] misc_coeff 

45 +predict(x) 

46 +activate_index(alpha, beta) 

47 +add_surrogate(alpha, beta) 

48 +update_misc_coeff() 

49 } 

50 class BaseInterpolator { 

51 <<abstract>> 

52 +tuple beta 

53 +list[BaseRV] x_vars 

54 +np.ndarray xi 

55 +np.ndarray yi 

56 +set_yi() 

57 +refine() 

58 +__call__(x) 

59 } 

60 } 

61 class SparseGridSurrogate { 

62 +np.ndarray x_grids 

63 +dict xi_map 

64 +dict yi_map 

65 +get_tensor_grid(alpha, beta) 

66 } 

67 class LagrangeInterpolator { 

68 +np.ndarray x_grids 

69 +np.ndarray weights 

70 +get_grid_sizes() 

71 +leja_1d() 

72 } 

73 class BaseRV { 

74 <<abstract>> 

75 +tuple bounds 

76 +str units 

77 +float nominal 

78 +pdf(x) 

79 +sample(size) 

80 } 

81 class UniformRV { 

82 +str type 

83 +get_uniform_bounds(nominal) 

84 } 

85 SystemSurrogate o-- "1..n" ComponentSurrogate 

86 ComponentSurrogate o-- "1..n" BaseInterpolator 

87 direction LR 

88 ComponentSurrogate <|-- SparseGridSurrogate 

89 BaseInterpolator <|-- LagrangeInterpolator 

90 SparseGridSurrogate ..> LagrangeInterpolator 

91 BaseRV <|-- UniformRV 

92``` 

93Note how the `SystemSurrogate` aggregates the `ComponentSurrogate`, which aggregates the `BaseInterpolator`. In other 

94words, interpolators can act independently of components, and components can act independently of systems. All three 

95make use of the random variables (these connections and some RVs are not shown for visual clarity). Currently, the only 

96underlying surrogate method that is implemented here is Lagrange polynomial interpolation (i.e. the 

97`LagrangeInterpolator`). If one wanted to use neural networks instead, the only change required is a new 

98implementation of `BaseInterpolator`. 

99""" 

100import numpy as np 

101 

102from amisc.interpolator import BaseInterpolator 

103from amisc.rv import BaseRV 

104 

105__version__ = "0.3.0" 

106 

107# Custom types that are used frequently 

108IndexSet = list[tuple[tuple, tuple]] 

109MiscTree = dict[str: dict[str: float | BaseInterpolator]] 

110InterpResults = BaseInterpolator | tuple[list[int | tuple | str], np.ndarray, BaseInterpolator] 

111IndicesRV = list[int | str | BaseRV] | int | str | BaseRV