pypharm 1.6.2__py3-none-any.whl → 1.6.3__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.
@@ -4,9 +4,9 @@ import numpy as np
4
4
  from scipy.integrate import solve_ivp, RK45
5
5
  from scipy.integrate import simps
6
6
  from scipy.optimize import minimize
7
- from PyPharm.algorithms.country_optimization import CountriesAlgorithm
8
- from PyPharm.algorithms.country_optimization_v2 import CountriesAlgorithm_v2
9
- from PyPharm.algorithms.genetic_optimization import GeneticAlgorithm
7
+ from krashemit.algorithms.country_optimization import CountriesAlgorithm
8
+ from krashemit.algorithms.country_optimization_v2 import CountriesAlgorithm_v2
9
+ from krashemit.algorithms.genetic_optimization import GeneticAlgorithm
10
10
  from numba import njit
11
11
  import matplotlib.pyplot as plt
12
12
 
PyPharm/models/pbpk.py CHANGED
@@ -3,9 +3,9 @@ import matplotlib
3
3
  import numpy as np
4
4
  from scipy.integrate import solve_ivp, LSODA
5
5
  from scipy.optimize import minimize
6
- from PyPharm.algorithms.country_optimization import CountriesAlgorithm
7
- from PyPharm.algorithms.country_optimization_v2 import CountriesAlgorithm_v2
8
- from PyPharm.algorithms.genetic_optimization import GeneticAlgorithm
6
+ from krashemit.algorithms.country_optimization import CountriesAlgorithm
7
+ from krashemit.algorithms.country_optimization_v2 import CountriesAlgorithm_v2
8
+ from krashemit.algorithms.genetic_optimization import GeneticAlgorithm
9
9
  from PyPharm.constants import MODEL_CONST, ANIMALS
10
10
  from numba import njit, types, cfunc
11
11
  from numba.typed import Dict
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pypharm
3
- Version: 1.6.2
3
+ Version: 1.6.3
4
4
  Summary: Module for solving pharmacokinetic problems
5
5
  Home-page: https://github.com/Krash13/PyPharm
6
6
  Author: Krash13
@@ -13,6 +13,7 @@ Classifier: License :: OSI Approved :: BSD License
13
13
  Classifier: Operating System :: OS Independent
14
14
  Requires-Python: >=3.9
15
15
  Description-Content-Type: text/markdown
16
+ Requires-Dist: krashemit (>=1.0.0)
16
17
  Requires-Dist: numpy (>=1.22.1)
17
18
  Requires-Dist: scipy (<=1.13.0)
18
19
  Requires-Dist: numba (>=0.58.1)
@@ -0,0 +1,9 @@
1
+ PyPharm/__init__.py,sha256=2HYYSesc-mjv-S9Q1Jm8yiLCZNmUGvlYCOWC8znJKok,158
2
+ PyPharm/constants.py,sha256=KovwTSSkiGh9o0Hf-yoqw3H7GxC_YmawunlWMHtSK98,3869
3
+ PyPharm/models/__init__.py,sha256=uCPwMYWOLdxiMZJ4eeVzee6Nrafot5gbCVsHXnHWuM0,196
4
+ PyPharm/models/compartment_models.py,sha256=LjMn8T7IVUywRj0rNnS0VQm26ZmPtveoF_X74Cg2KsE,51317
5
+ PyPharm/models/pbpk.py,sha256=ENkhi_BLxZ2s2tnrgCHmlJljZxBfvofdWSHtT3VKUM4,30645
6
+ pypharm-1.6.3.dist-info/METADATA,sha256=KkFIqDUAxcvC9yAf1F3x6qkrphYkxtL6TTeIh68T-2Y,23011
7
+ pypharm-1.6.3.dist-info/WHEEL,sha256=OqRkF0eY5GHssMorFjlbTIq072vpHpF60fIQA6lS9xA,92
8
+ pypharm-1.6.3.dist-info/top_level.txt,sha256=yybfSkKw8q1G3aEcnlfVL7_L9ufGFSAYZnpc7q6oYJk,8
9
+ pypharm-1.6.3.dist-info/RECORD,,
File without changes
@@ -1,469 +0,0 @@
1
- import random
2
- import numpy as np
3
- from operator import attrgetter
4
- from math import ceil, cos, sin
5
-
6
-
7
- class Individual:
8
-
9
- def __init__(self, x, function):
10
- self.x = x
11
- self.f = function(self.x)
12
- self.ep_n = 0
13
-
14
- def update_function(self, function):
15
- self.f = function(self.x)
16
-
17
- @classmethod
18
- def crossing(cls, individual1, individual2, p, function, Xmin, Xmax):
19
- x1 = []
20
- x2 = []
21
- for i in range(len(individual1.x)):
22
- if i % 2:
23
- x1.append(individual1.x[i])
24
- x2.append(individual2.x[i])
25
- else:
26
- x1.append(individual2.x[i])
27
- x2.append(individual1.x[i])
28
- x1[i] += random.uniform(-p * x1[i], p * x1[i])
29
- x1[i] = x1[i] if x1[i] >= Xmin[i] else Xmin[i]
30
- x1[i] = x1[i] if x1[i] <= Xmax[i] else Xmax[i]
31
- x2[i] += random.uniform(-p * x2[i], p * x2[i])
32
- x2[i] = x2[i] if x2[i] >= Xmin[i] else Xmin[i]
33
- x2[i] = x2[i] if x2[i] <= Xmax[i] else Xmax[i]
34
- return [cls(x1, function), cls(x2, function)]
35
-
36
- @classmethod
37
- def crossing2(cls, individual1, individual2, p, function, Xmin, Xmax):
38
- x1 = []
39
- x2 = []
40
- random_list = list(range(len(individual1.x)))
41
- random.shuffle(random_list)
42
- random_list = random_list[:len(individual1.x) // 2]
43
- for i in range(len(individual1.x)):
44
- if i in random_list:
45
- x1.append(individual1.x[i])
46
- x2.append(individual2.x[i])
47
- else:
48
- x1.append(individual2.x[i])
49
- x2.append(individual1.x[i])
50
- x1[i] += random.uniform(-p * x1[i], p * x1[i])
51
- x1[i] = x1[i] if x1[i] >= Xmin[i] else Xmin[i]
52
- x1[i] = x1[i] if x1[i] <= Xmax[i] else Xmax[i]
53
- x2[i] += random.uniform(-p * x2[i], p * x2[i])
54
- x2[i] = x2[i] if x2[i] >= Xmin[i] else Xmin[i]
55
- x2[i] = x2[i] if x2[i] <= Xmax[i] else Xmax[i]
56
- return [cls(x1, function), cls(x2, function)]
57
-
58
- @classmethod
59
- def crossing3(cls, individual1, individual2, p, function, Xmin, Xmax):
60
- x1 = []
61
- x2 = []
62
- max_n = len(individual1.x) // 2
63
- n = random.randint(1, max_n)
64
- l = []
65
- for i in range(len(individual1.x) // n):
66
- l += [j + 2 * i * n for j in range(n) if j + 2 * i * n < len(individual1.x)]
67
- for i in range(len(individual1.x)):
68
- if i in l:
69
- x1.append(individual1.x[i])
70
- x2.append(individual2.x[i])
71
- else:
72
- x1.append(individual2.x[i])
73
- x2.append(individual1.x[i])
74
- x1[i] += random.uniform(-p * x1[i], p * x1[i])
75
- x1[i] = x1[i] if x1[i] >= Xmin[i] else Xmin[i]
76
- x1[i] = x1[i] if x1[i] <= Xmax[i] else Xmax[i]
77
- x2[i] += random.uniform(-p * x2[i], p * x2[i])
78
- x2[i] = x2[i] if x2[i] >= Xmin[i] else Xmin[i]
79
- x2[i] = x2[i] if x2[i] <= Xmax[i] else Xmax[i]
80
- return [cls(x1, function), cls(x2, function)]
81
-
82
- @classmethod
83
- def crossing4(cls, individual1, individual2, p, function, Xmin, Xmax):
84
- x1 = []
85
- x2 = []
86
- for i in range(len(individual1.x)):
87
- x1.append((individual1.x[i] + individual2.x[i]) / 2)
88
- x2.append((individual1.x[i] + individual2.x[i]) / 2)
89
- x2[i] += random.uniform(-p * x2[i], p * x2[i])
90
- x2[i] = x2[i] if x2[i] >= Xmin[i] else Xmin[i]
91
- x2[i] = x2[i] if x2[i] <= Xmax[i] else Xmax[i]
92
- return [cls(x1, function), cls(x2, function)]
93
-
94
- @classmethod
95
- def crossing5(cls, individual1, individual2, p, function, Xmin, Xmax):
96
- x1 = []
97
- # x2 = []
98
- for i in range(len(individual1.x)):
99
- x1.append((individual1.x[i] + individual2.x[i]) / 2)
100
- # x2.append((individual1.x[i] + individual2.x[i]) / 2)
101
- # x2[i] += random.uniform(-p * x2[i], p * x2[i])
102
- # x2[i] = x2[i] if x2[i] >= Xmin[i] else Xmin[i]
103
- # x2[i] = x2[i] if x2[i] <= Xmax[i] else Xmax[i]
104
- return [cls(x1, function)] #, cls(x2, function)]
105
-
106
- @classmethod
107
- def crossing6(cls, individual1, individual2, p, function, Xmin, Xmax):
108
- x1 = []
109
- k = random.random()
110
- if k > 0.5:
111
- x2 = []
112
- for i in range(len(individual1.x)):
113
- x1.append((individual1.x[i] + individual2.x[i]) / 2)
114
- if k > 0.5:
115
- x2.append((individual1.x[i] + individual2.x[i]) / 2)
116
- x2[i] += random.uniform(-p * x2[i], p * x2[i])
117
- x2[i] = x2[i] if x2[i] >= Xmin[i] else Xmin[i]
118
- x2[i] = x2[i] if x2[i] <= Xmax[i] else Xmax[i]
119
- if k > 0.5:
120
- return [cls(x1, function), cls(x2, function)]
121
- return [cls(x1, function)]
122
-
123
- @classmethod
124
- def crossing7(cls, individual1, individual2, p, function, Xmin, Xmax):
125
- k = random.random()
126
- if k <= 1 / 3:
127
- return Individual.crossing4(individual1, individual2, p, function, Xmin, Xmax)
128
- elif k <= 2 / 3:
129
- return Individual.crossing8(individual1, individual2, p, function, Xmin, Xmax)
130
- else:
131
- return Individual.crossing6(individual1, individual2, p, function, Xmin, Xmax)
132
-
133
- @classmethod
134
- def crossing8(cls, individual1, individual2, p, function, Xmin, Xmax):
135
- new_x = []
136
- alpha = 0.5
137
- for i in range(len(individual1.x)):
138
- c_min = min(individual1.x[i], individual2.x[i])
139
- c_max = max(individual1.x[i], individual2.x[i])
140
- I = c_max - c_min
141
- new_x.append(random.uniform(c_min - I * alpha, c_max + I * alpha))
142
- new_x = np.clip(new_x, Xmin, Xmax)
143
- return [cls(new_x, function)]
144
-
145
-
146
- @classmethod
147
- def crossing9(cls, individual1, individual2, p, function, Xmin, Xmax):
148
- new_x = []
149
- alpha = 0.5
150
- for i in range(len(individual1.x)):
151
- c_min = min(individual1.x[i], individual2.x[i])
152
- c_max = max(individual1.x[i], individual2.x[i])
153
- I = c_max - c_min
154
- new_x.append(random.uniform(c_min - I * alpha, c_max + I * alpha))
155
- new_x = np.clip(new_x, Xmin, Xmax)
156
- if random.random() <= 0.5:
157
- for i in range(len(individual1.x)):
158
- new_x[i] += random.uniform(-p * new_x[i], p * new_x[i])
159
- new_x = np.clip(new_x, Xmin, Xmax)
160
- return [cls(new_x, function)]
161
-
162
- @classmethod
163
- def crossing10(cls, individual1, individual2, p, function, Xmin, Xmax, p2):
164
- k = random.random()
165
- if k <= 1 / 3:
166
- return Individual.crossing9(individual1, individual2, p, function, Xmin, Xmax, p2)
167
- else:
168
- return Individual.crossing8(individual1, individual2, p, function, Xmin, Xmax)
169
-
170
- @classmethod
171
- def crossing11(cls, individual1, individual2, p, function, Xmin, Xmax):
172
- new_x = []
173
- alpha = p
174
- for i in range(len(individual1.x)):
175
- c_min = min(individual1.x[i], individual2.x[i])
176
- c_max = max(individual1.x[i], individual2.x[i])
177
- I = c_max - c_min
178
- new_x.append(random.uniform(c_min - I * alpha, c_max + I * alpha))
179
- new_x = np.clip(new_x, Xmin, Xmax)
180
- return [cls(new_x, function)]
181
-
182
- def mutation(self, Xmin, Xmax, function, pmax):
183
- self.ep_n += 1
184
- for i in range(len(self.x)):
185
- self.x[i] += pmax * random.uniform(-self.x[i], self.x[i]) / self.ep_n
186
- self.x[i] = self.x[i] if self.x[i] >= Xmin[i] else Xmin[i]
187
- self.x[i] = self.x[i] if self.x[i] <= Xmax[i] else Xmax[i]
188
- self.update_function(function)
189
-
190
-
191
- class Country:
192
-
193
- def __init__(self, Xmin, Xmax, N, function):
194
- x_min = []
195
- x_max = []
196
- for i in range(len(Xmin)):
197
- x_min.append(random.uniform(Xmin[i], Xmax[i]))
198
- x_max.append(random.uniform(x_min[i], Xmax[i]))
199
- self.population = []
200
- for i in range(N):
201
- x = []
202
- for j in range(len(Xmin)):
203
- x.append(random.uniform(x_min[j], x_max[j]))
204
- self.population.append(Individual(x, function))
205
- self.sort_population()
206
- self.action = None
207
- self.enemy = None
208
- self.ally = None
209
-
210
- @property
211
- def best_function(self):
212
- return self.population[0].f
213
-
214
- @property
215
- def avg_function(self):
216
- return sum([individual.f for individual in self.population]) / len(self.population)
217
-
218
- def update_population(self, function):
219
- for individual in self.population:
220
- individual.update_function(function)
221
-
222
- def sort_population(self):
223
- self.population.sort(key=attrgetter('f'))
224
-
225
- def reproduction(self, n_min, n_max, p_min, p_max, f_min, f_max, ti, t_max, function, Xmin, Xmax):
226
- n = ceil((n_max - n_min) * (f_max - self.avg_function) / (f_max - f_min) + n_min)
227
- n = np.clip(n, n_min, n_max)
228
- p = (p_max - p_min) * (1 - ti / t_max) * (self.avg_function - f_min) / (f_max - f_min) + p_min
229
- p = np.clip(p, p_min, p_max)
230
- # p2 = (1 - ti / t_max) * (self.avg_function - f_min) / (f_max - f_min)
231
- new_individuals = []
232
-
233
- for i in range(n):
234
- if len(self.population) == 2 and self.population[0] == self.population[1]:
235
- new_individuals.extend(Individual.crossing11(self.population[0], self.population[1], p, function, Xmin, Xmax))
236
- continue
237
- k1 = random.randint(0, len(self.population) - 1)
238
- individual1 = self.population[k1]
239
- k2 = k1
240
- while k2 == k1:
241
- k2 = random.randint(0, len(self.population) - 1)
242
- individual2 = self.population[k2]
243
- new_individuals.extend(Individual.crossing11(individual1, individual2, p, function, Xmin, Xmax))
244
- self.population.extend(new_individuals)
245
- self.sort_population()
246
-
247
- def extinction(self, m_min, m_max, f_min, f_max):
248
- m = int((m_max - m_min) * (self.avg_function - f_min) / (f_max - f_min) + m_min)
249
- m = m if m <= m_max else m_max
250
- m = m if m >= m_min else m_min
251
- self.population = self.population[:-m]
252
-
253
- def select_action(self, countries):
254
- self.action = random.randint(0, 3)
255
- if self.action == 1:
256
- ally_list = [country for country in countries if country.action is None and country != self]
257
- if ally_list:
258
- self.ally = ally_list.pop(random.randint(0, len(ally_list) - 1))
259
- self.ally.action = 1
260
- self.ally.ally = self
261
- else:
262
- self.action = random.choice([0, 3])
263
- if self.action == 2:
264
- enemy_list = [country for country in countries if country.action is None and country != self]
265
- if enemy_list:
266
- self.enemy = enemy_list.pop(random.randint(0, len(enemy_list) - 1))
267
- self.enemy.action = 2
268
- self.enemy.enemy = self
269
- else:
270
- self.action = random.choice([0, 3])
271
-
272
- def epedemic(self, elite, dead, function, Xmin, Xmax, p_max):
273
- n_elite = ceil(elite * len(self.population))
274
- n_dead = ceil(dead * len(self.population))
275
- self.population = self.population[:-n_dead]
276
- for individual in self.population[n_elite:]:
277
- individual.mutation(Xmin, Xmax, function, p_max)
278
- self.sort_population()
279
- self.action = None
280
-
281
- # def sabotage(self, n_copy):
282
- # for i in range(n_copy):
283
- # self.enemy.population.append(copy.copy(self.population[0]))
284
- # self.action = None
285
- # self.enemy = None
286
-
287
- def motion(self, function, Xmin, Xmax):
288
- x_best = self.population[0].x
289
- for i in range(1, len(self.population)):
290
- for j in range(len(x_best)):
291
- self.population[i].x[j] += random.uniform(0, 2) * (x_best[j] - self.population[i].x[j])
292
- self.population[i].x[j] = self.population[i].x[j] if self.population[i].x[j] >= Xmin[j] else Xmin[j]
293
- self.population[i].x[j] = self.population[i].x[j] if self.population[i].x[j] <= Xmax[j] else Xmax[j]
294
- self.update_population(function)
295
- self.sort_population()
296
- self.action = None
297
-
298
- @staticmethod
299
- def trade(country1, country2, k):
300
- trade_list1 = []
301
- trade_list2 = []
302
- if len(country1.population) <= k or len(country2.population) <= k:
303
- k = min(len(country1.population), len(country2.population)) // 2
304
- for i in range(k):
305
- trade_list1.append(country1.population.pop(random.randint(0, len(country1.population) - 1)))
306
- trade_list2.append(country2.population.pop(random.randint(0, len(country2.population) - 1)))
307
- country1.population.extend(trade_list2)
308
- country2.population.extend(trade_list1)
309
- country1.sort_population()
310
- country2.sort_population()
311
- country1.action = None
312
- country2.action = None
313
- country1.ally = None
314
- country2.ally = None
315
-
316
- @staticmethod
317
- def war(country1, country2, l):
318
- war_list1 = []
319
- war_list2 = []
320
- if len(country1.population) <= l or len(country2.population) <= l:
321
- l = min(len(country1.population), len(country2.population))
322
- for i in range(l):
323
- war_list1.append(country1.population.pop(random.randint(0, len(country1.population) - 1)))
324
- war_list2.append(country2.population.pop(random.randint(0, len(country2.population) - 1)))
325
- wins1 = 0
326
- wins2 = 0
327
- for i in range(l-1, -1, -1):
328
- if war_list1[i].f < war_list2[i].f:
329
- war_list2.pop(i)
330
- wins1 += 1
331
- elif war_list1[i].f > war_list2[i].f:
332
- war_list1.pop(i)
333
- wins2 += 1
334
- if wins1 > wins2:
335
- country1.population.extend(war_list1)
336
- country1.population.extend(war_list2)
337
- elif wins2 > wins1:
338
- country2.population.extend(war_list1)
339
- country2.population.extend(war_list2)
340
- else:
341
- country1.population.extend(war_list1)
342
- country2.population.extend(war_list2)
343
- country1.sort_population()
344
- country2.sort_population()
345
- country1.action = None
346
- country2.action = None
347
- country1.enemy = None
348
- country2.enemy = None
349
-
350
-
351
- class CountriesAlgorithm:
352
-
353
- def __init__(self, f, Xmin, Xmax, M, N, n, p, m, k, l, ep, tmax, printing=False, memory_list=None):
354
- self.f = f
355
- self.Xmin = Xmin
356
- self.Xmax = Xmax
357
- self.n = n
358
- self.p = p
359
- self.m = m
360
- self.k = k
361
- self.l = l
362
- self.ep = ep
363
- self.tmax = tmax
364
- self.countries = []
365
- self.printing = printing
366
- self.memory_list = memory_list
367
- for i in range(M):
368
- self.countries.append(Country(self.Xmin, self.Xmax, N, self.f))
369
-
370
- def start(self):
371
- ti = 0
372
- motion = 0
373
- trade = 0
374
- war = 0
375
- epedemic = 0
376
- if self.memory_list is not None:
377
- self.memory_list[0] = False
378
- while ti <= self.tmax:
379
- ti += 1
380
- for country in self.countries:
381
- if country.action is None:
382
- country.select_action(self.countries)
383
- for country in self.countries:
384
- if country.action == 0:
385
- motion += 1
386
- country.motion(
387
- function=self.f,
388
- Xmin=self.Xmin,
389
- Xmax=self.Xmax
390
- )
391
- elif country.action == 1:
392
- trade += 1
393
- Country.trade(
394
- country1=country,
395
- country2=country.ally,
396
- k=self.k
397
- )
398
- elif country.action == 2:
399
- war += 1
400
- Country.war(
401
- country1=country,
402
- country2=country.enemy,
403
- l=self.l
404
- )
405
- elif country.action == 3:
406
- epedemic += 1
407
- country.epedemic(
408
- elite=self.ep[0],
409
- dead=self.ep[1],
410
- Xmin=self.Xmin,
411
- Xmax=self.Xmax,
412
- function=self.f,
413
- p_max=self.p[1],
414
- )
415
- self.countries = [country for country in self.countries if country.population]
416
- self.countries = sorted(self.countries, key=attrgetter('avg_function'))
417
- if not self.countries:
418
- break
419
- f_min = self.countries[0].avg_function
420
- f_max = self.countries[-1].avg_function
421
- if f_min == f_max:
422
- self.countries = sorted(self.countries, key=attrgetter('best_function'))
423
- result = self.countries[0].population[0]
424
- break
425
- e_individuals = []
426
- for country in self.countries:
427
- if len(country.population) == 1:
428
- e_individuals.append(country.population[0])
429
- continue
430
- if country.population:
431
- country.reproduction(
432
- n_min=self.n[0],
433
- n_max=self.n[1],
434
- p_min=self.p[0],
435
- p_max=self.p[1],
436
- f_min=f_min,
437
- f_max=f_max,
438
- ti=ti,
439
- t_max=self.tmax,
440
- function=self.f,
441
- Xmin=self.Xmin,
442
- Xmax=self.Xmax
443
- )
444
- country.extinction(
445
- m_min=self.m[0],
446
- m_max=self.m[1],
447
- f_min=f_min,
448
- f_max=f_max
449
- )
450
- self.countries = [country for country in self.countries if country.population]
451
- for individual in e_individuals:
452
- random_country = self.countries[random.randint(0, len(self.countries) - 1)]
453
- random_country.population.append(individual)
454
- random_country.sort_population()
455
- self.countries = sorted(self.countries, key=attrgetter('best_function'))
456
- if not self.countries:
457
- break
458
- result = self.countries[0].population[0]
459
-
460
- if self.printing:
461
- print(f"{ti}) Лучшее решение: {result.x} - {result.f}, Стран осталось: {len(self.countries)}, Движение/Обмен/Войны/Эпидемии: {motion}/{trade}/{war}/{epedemic}")
462
- print(f"Общее количество особей: {sum([len(country.population) for country in self.countries])}")
463
-
464
- if self.memory_list is not None:
465
- self.memory_list[0] = ti
466
- for i in range(len(result.x)):
467
- self.memory_list[i + 1] = float(result.x[i])
468
- self.memory_list[-1] = float(result.f)
469
- return (result.x, result.f, False, ti)