mosaictools 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.
@@ -0,0 +1,17 @@
1
+ Metadata-Version: 2.1
2
+ Name: mosaictools
3
+ Version: 0.1.0
4
+ Summary: Surrogate modelling of modal properties using MOSAIC method
5
+ Home-page: https://github.com/blazkurent/mosaictools/
6
+ Author: Blaž Kurent
7
+ Author-email: blaz.kurent@fgg.uni-lj.si
8
+ License: UNKNOWN
9
+ Description: # mosaictools
10
+ Python library for surrogate modelling of modal properties according to the Mode-Shape-Adapted Input parameter domain Curring (MOSAIC) method.
11
+
12
+ Platform: UNKNOWN
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Development Status :: 3 - Alpha
17
+ Description-Content-Type: text/markdown
@@ -0,0 +1,2 @@
1
+ # mosaictools
2
+ Python library for surrogate modelling of modal properties according to the Mode-Shape-Adapted Input parameter domain Curring (MOSAIC) method.
@@ -0,0 +1,2 @@
1
+ __version__ = '0.1.0'
2
+ from .main import *
@@ -0,0 +1,115 @@
1
+ # from polysys import LegendrePolynomials
2
+ import numpy as np
3
+ from scipy.stats.qmc import Halton as ghalton
4
+
5
+ # class Distributin():
6
+ # def sample(self, n):
7
+ # xi = np.random.rand(n)
8
+ # return self.invcdf(xi)
9
+
10
+
11
+ class UniformDistribution():
12
+ def __init__(self, a=0, b=1):
13
+ self.a = a
14
+ self.b = b
15
+
16
+ def __repr__(self):
17
+ return 'U({}, {})'.format(self.a, self.b)
18
+
19
+ def pdf(self, x):
20
+ a = self.a
21
+ b = self.b
22
+ y = 1 / (b - a) * np.ones(x.shape)
23
+ y[x < a] = 0
24
+ y[x > b] = 0
25
+ return y
26
+
27
+ def cdf(self, x):
28
+ a = self.a
29
+ b = self.b
30
+ y = (x - a) / (b - a)
31
+ y[x < a] = 0
32
+ y[x > b] = 1
33
+ return y
34
+
35
+ def invcdf(self, y):
36
+ a = self.a
37
+ b = self.b
38
+ x = np.full(y.shape, np.nan)
39
+ ind = (y >= 0) & (y <= 1)
40
+
41
+ x[ind] = a + (b - a) * y[ind]
42
+ return x
43
+
44
+ def sample(self, n, method='MC'):
45
+ if method == 'MC':
46
+ xi = np.random.rand(n)
47
+ elif method == 'QMC':
48
+ gen = ghalton.Halton(1)
49
+ xi = np.array(gen.get(n)) # dummy generation to avoid sample point q = 0
50
+ return self.invcdf(xi)
51
+
52
+ def moments(self):
53
+ return self.mean(), self.var(), self.skew(), self.kurt()
54
+
55
+ def mean(self):
56
+ return 0.5 * (self.a + self.b)
57
+
58
+ def var(self):
59
+ return (self.b - self.a) ** 2 / 12
60
+
61
+ def skew(self):
62
+ return 0
63
+
64
+ def kurt(self):
65
+ return -6 / 5
66
+
67
+ def translate(self, shift, scale):
68
+ m = (self.a + self.b) / 2
69
+ v = scale * (self.b - self.a) / 2
70
+
71
+ self.a = m + shift - v
72
+ self.b = m + shift + v
73
+
74
+ def get_base_dist(self):
75
+ dist_germ = UniformDistribution(-1, 1)
76
+ return dist_germ
77
+
78
+ def base2dist(self, y):
79
+ return self.mean() + y * (self.b - self.a) / 2
80
+
81
+ def dist2base(self, x):
82
+ return (x - self.mean()) * 2 / (self.b - self.a)
83
+
84
+ # def orth_polysys(self, normalized):
85
+ # if self.a == -1 & self.b == 1:
86
+ # if normalized:
87
+ # polysys = LegendrePolynomials()
88
+ # else:
89
+ # polysys = LegendrePolynomials().normalized()
90
+ # else:
91
+ # polysys = []
92
+ # return polysys
93
+
94
+ def orth_polysys_syschar(self, normalized):
95
+ if self.a == -1 and self.b == 1:
96
+ if normalized:
97
+ polysys_char = 'p'
98
+ else:
99
+ polysys_char = 'P'
100
+ else:
101
+ polysys_char = []
102
+ return polysys_char
103
+
104
+
105
+ if __name__ == "__main__":
106
+ dist = UniformDistribution(-2,2)
107
+ print(dist.moments())
108
+ print(dist.pdf(np.array([-3,-2,-1,0,1,2,3])))
109
+ print(dist.cdf(np.array([-3, -2, -1, 0, 1, 2, 3])))
110
+ print(dist.get_base_dist().a, dist.get_base_dist().b)
111
+ print(dist.dist2base(np.array([-3, -2, -1, 0, 1, 2, 3])))
112
+ print(dist.base2dist(np.array([-2, -1, -0.5, 0, 0.5, 1, 2])))
113
+
114
+
115
+
@@ -0,0 +1,15 @@
1
+ from polysys import *
2
+
3
+ def syschar_to_polysys(syschar):
4
+ poly_dict = {'H': HermitePolynomials,
5
+ 'h': HermitePolynomials.normalized(),
6
+ 'P': LegendrePolynomials,
7
+ 'p': LegendrePolynomials.normalized(),
8
+ 'T': ChebyshevTPolynomials,
9
+ 't': ChebyshevTPolynomials.normalized(),
10
+ 'U': ChebyshevUPolynomials,
11
+ 'u': ChebyshevUPolynomials.normalized(),
12
+ 'L': LaguerrePolynomials,
13
+ 'l': LaguerrePolynomials.normalized(),
14
+ 'M': Monomials}
15
+ return poly_dict[syschar]
@@ -0,0 +1,150 @@
1
+ import numpy as np
2
+ from multiindex import *
3
+ from gpc_functions import syschar_to_polysys
4
+
5
+ # ##########################################################################################
6
+ # GPC SURROGATE MODEL
7
+ # ##########################################################################################
8
+ class GpcSurrogateModel:
9
+ def __init__(self, Q, p=0, I="default", full_tensor=False, **kwargs):
10
+ self.basis = GpcBasis(Q, p=p, I="default", full_tensor=False)
11
+ self.Q = Q
12
+ self.u_i_alpha = []
13
+
14
+ def __repr__(self):
15
+ attrs = vars(self)
16
+ return ', '.join("%s: %s" % item for item in attrs.items())
17
+
18
+ def compute_coeffs_by_regression(self, q_j_k, u_i_k):
19
+ xi_j_k = self.Q.params2germ(q_j_k)
20
+ phi_alpha_k = self.basis.evaluate(xi_j_k)
21
+ u_i_alpha = np.matmul(u_i_k, np.linalg.pinv(phi_alpha_k))
22
+ self.u_i_alpha = u_i_alpha
23
+
24
+ def compute_coeffs_by_projection(self, q_j_k, u_i_k, w_k):
25
+ xi_j_k = self.Q.params2germ(q_j_k)
26
+ phi_alpha_k = self.basis.evaluate(xi_j_k)
27
+ u_i_alpha = np.matmul(u_i_k, np.diag(w_k), phi_alpha_k.transpose())
28
+ self.u_i_alpha = u_i_alpha
29
+
30
+ def predict_response(self, q_j_k):
31
+ xi_j_k = self.Q.params2germ(q_j_k)
32
+ phi_alpha_k = self.basis.evaluate(xi_j_k)
33
+ u_i_j = np.matmul(self.u_i_alpha, phi_alpha_k)
34
+ return u_i_j
35
+
36
+
37
+
38
+ # ##########################################################################################
39
+ # GPC BASIS
40
+ # ##########################################################################################
41
+ class GpcBasis:
42
+ # ---------------------Initialization---------------------------------------------------
43
+ def __init__(self, Q, p=0, I="default", full_tensor=False, **kwargs):
44
+ m = Q.num_params()
45
+ self.m = m
46
+
47
+ self.syschars = Q.get_gpc_syschars()
48
+ self.p = p
49
+
50
+ if I == "default":
51
+ self.I = multiindex(self.m, p, full_tensor=full_tensor)
52
+ else:
53
+ self.I = I
54
+
55
+ # ---------------------set how gpc looks when printed ---------------------------------------------------
56
+ def __repr__(self):
57
+ attrs = vars(self)
58
+ return ', '.join("%s: %s" % item for item in attrs.items())
59
+
60
+ # ----------------------------------------- size --------------------------------------------------
61
+ def size(self):
62
+ return [self.I.shape]
63
+
64
+ # ----------------------------Evaluate basis functions ---------------------------------------------------
65
+ def evaluate(self, xi, dual=False):
66
+ syschars = self.syschars
67
+ I = self.I
68
+ m = self.m
69
+ M = self.I.shape[0]
70
+ if xi.ndim == 1:
71
+ xi = xi.reshape(-1, 1)
72
+ k = xi.shape[1]
73
+ deg = max(self.I.flatten())
74
+
75
+ p = np.zeros([m, k, deg + 2])
76
+ p[:, :, 0] = np.zeros(xi.shape)
77
+ p[:, :, 1] = np.ones(xi.shape)
78
+
79
+ if len(syschars) == 1:
80
+ polysys = syschar_to_polysys(syschars)
81
+ r = polysys.recur_coeff(syschars, deg)
82
+ for d in range(deg):
83
+ p[:, :, d + 2] = (r[d, 0] + xi * r[d, 1]) * p[:, :, d + 1] - r[d, 2] * p[:, :, d]
84
+ else:
85
+ for j, syschar in enumerate(syschars):
86
+ polysys = syschar_to_polysys(syschar)
87
+ r = polysys.recur_coeff(deg)
88
+ for d in range(deg):
89
+ p[j, :, d + 2] = (r[d, 0] + xi[j, :] * r[d, 1]) * p[j, :, d + 1] - r[d, 2] * p[j, :, d]
90
+
91
+ y_alpha_j = np.ones([M, k])
92
+ for j in range(m):
93
+ y_alpha_j = y_alpha_j * p[j, :, I[:, j] + 1]
94
+
95
+ if dual:
96
+ nrm2 = self.norm(do_sqrt=False)
97
+ y_alpha_j = (y_alpha_j / nrm2.reshape(-1, 1)).transpose()
98
+ return y_alpha_j
99
+
100
+ # ------------------------Compute the norm of the basis functions-----------------------
101
+ def norm(self, do_sqrt=True):
102
+ syschars = self.syschars
103
+ I = self.I
104
+ m = self.m
105
+ M = self.I.shape[0]
106
+
107
+ if syschars == syschars.lower():
108
+ norm_I = np.ones([M, 1])
109
+ return norm_I
110
+
111
+ if len(syschars) == 1:
112
+ # max degree of univariate polynomials
113
+ deg = max(self.I.flatten())
114
+ polysys = syschar_to_polysys(syschars)
115
+ nrm = polysys.sqnorm(range(deg + 1))
116
+ norm2_I = np.prod(nrm[I].reshape(I.shape), axis=1)
117
+
118
+ else:
119
+ norm2_I = np.ones([M])
120
+ for j in range(m):
121
+ deg = max(I[:, j])
122
+ polysys = syschar_to_polysys(syschars[j])
123
+ nrm2 = polysys.sqnorm(np.arange(deg + 1))
124
+ norm2_I = norm2_I * nrm2[I[:, j]]
125
+ if do_sqrt:
126
+ norm_I = np.sqrt(norm2_I)
127
+ else:
128
+ norm_I = norm2_I
129
+
130
+ return norm_I
131
+
132
+
133
+ # ##########################################################################################
134
+ # UTILS
135
+ # ##########################################################################################
136
+
137
+ #
138
+ # ##########################################################################################
139
+ # TEST
140
+ # ##########################################################################################
141
+ def main():
142
+ print(multiindex(3, 4))
143
+ gPCE = GpcSurrogateModel('PP', p=3)
144
+ gPCE.basis.norm()
145
+ print(gPCE.basis.evaluate(np.array([np.arange(-1, 1, 0.1)] * 2)))
146
+ print(gPCE)
147
+
148
+
149
+ if __name__ == "__main__":
150
+ main()