pyfemtet 0.6.0__py3-none-any.whl → 0.6.2__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.

Potentially problematic release.


This version of pyfemtet might be problematic. Click here for more details.

pyfemtet/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.6.0"
1
+ __version__ = "0.6.2"
pyfemtet/opt/_femopt.py CHANGED
@@ -1,7 +1,7 @@
1
1
  # built-in
2
2
  import inspect
3
3
  import warnings
4
- from typing import Optional, Any, Callable, List
4
+ from typing import Optional, Any, Callable, List, Sequence, SupportsFloat
5
5
  import os
6
6
  import datetime
7
7
  from time import time, sleep
@@ -363,6 +363,46 @@ class FEMOpt:
363
363
 
364
364
  self.opt.objectives[name] = Objective(fun, name, direction, args, kwargs)
365
365
 
366
+ def add_objectives(
367
+ self,
368
+ fun: Callable[[Any], Sequence[SupportsFloat]],
369
+ n_return: int,
370
+ names: str or Sequence[str] or None = None,
371
+ directions: str or Sequence[str] or None = None,
372
+ args: tuple or None = None,
373
+ kwargs: dict or None = None,
374
+ ):
375
+ from pyfemtet.opt._femopt_core import ObjectivesFunc
376
+ components = ObjectivesFunc(fun, n_return)
377
+
378
+ if names is not None:
379
+ if isinstance(names, str):
380
+ names = [f'name_{i}' for i in range(n_return)]
381
+ else:
382
+ # names = names
383
+ pass
384
+ else:
385
+ names = [None for _ in range(n_return)]
386
+
387
+ if directions is not None:
388
+ if isinstance(directions, str):
389
+ directions = [directions for _ in range(n_return)]
390
+ else:
391
+ # directions = directions
392
+ pass
393
+ else:
394
+ directions = ['minimize' for _ in range(n_return)]
395
+
396
+ for name, component, direction in zip(names, components, directions):
397
+ self.add_objective(
398
+ fun=component,
399
+ name=name,
400
+ direction=direction,
401
+ args=args,
402
+ kwargs=kwargs,
403
+ )
404
+
405
+
366
406
  def add_constraint(
367
407
  self,
368
408
  fun,
@@ -430,6 +430,79 @@ class Constraint(Function):
430
430
  super().__init__(fun, name, args, kwargs)
431
431
 
432
432
 
433
+ class ObjectivesFunc:
434
+ """複数の値を返す関数を objective として扱うためのクラス
435
+
436
+ 複数の値を返す関数を受け取る。
437
+
438
+ 最初に評価されたときに計算を実行し
439
+ そうでない場合は保持した値を返す
440
+ callable のリストを提供する。
441
+
442
+ """
443
+
444
+ def __init__(self, fun, n_return):
445
+ self._evaluated = [False for _ in range(n_return)]
446
+ self._values = [None for _ in range(n_return)]
447
+ self._i = 0
448
+ self.fun = fun
449
+ self.n_return = n_return
450
+
451
+ def __iter__(self):
452
+ return self
453
+
454
+ def __next__(self):
455
+
456
+ # iter の長さ
457
+ if self._i == self.n_return:
458
+ self._i = 0
459
+ raise StopIteration
460
+
461
+ # iter として提供する callable オブジェクト
462
+ # self の情報にもアクセスする必要があり
463
+ # それぞれが iter された時点での i 番目という
464
+ # 情報も必要なのでこのスコープで定義する必要がある
465
+ class NthFunc:
466
+ def __init__(self_, i):
467
+ # 何番目の要素であるかを保持
468
+ # self._i を直接参照すると
469
+ # 実行時点での ObjectiveFunc の
470
+ # 値を参照してしまう
471
+ self_.i = i
472
+
473
+ def __call__(self_, *args, **kwargs):
474
+ # 何番目の要素であるか
475
+ i = self_.i
476
+
477
+ # 一度も評価されていなければ評価する
478
+ if not any(self._evaluated):
479
+ self._values = tuple(self.fun(*args, **kwargs))
480
+ assert len(self._values) == self.n_return, '予期しない戻り値の数'
481
+
482
+ # 評価したらフラグを立てる
483
+ self._evaluated[i] = True
484
+
485
+ # すべてのフラグが立ったらクリアする
486
+ if all(self._evaluated):
487
+ self._evaluated = [False for _ in range(self.n_return)]
488
+
489
+ # 値を返す
490
+ return self._values[i]
491
+
492
+ @property
493
+ def __globals__(self_):
494
+ # ScapeGoat 実装への対処
495
+ return self.fun.__globals__
496
+
497
+ # callable を作成
498
+ f = NthFunc(self._i)
499
+
500
+ # index を更新
501
+ self._i += 1
502
+
503
+ return f
504
+
505
+
433
506
  class _HistoryDfCore:
434
507
  """Class for managing a DataFrame object in a distributed manner."""
435
508
 
@@ -129,7 +129,7 @@ class AbstractOptimizer(ABC):
129
129
  self.fem_class = None
130
130
  self.fem_kwargs = dict()
131
131
  self.variables: ExpressionEvaluator = ExpressionEvaluator()
132
- self.objectives: dict[str, Constraint] = dict()
132
+ self.objectives: dict[str, Objective] = dict()
133
133
  self.constraints: dict[str, Constraint] = dict()
134
134
  self.entire_status = None # actor
135
135
  self.history = None # actor
@@ -1,3 +1,41 @@
1
+ """This algorithm is based on BoTorchSampler of optuna_integration[1] and the paper[2].
2
+
3
+
4
+ ** LICENSE NOTICE OF [1] **
5
+
6
+ MIT License
7
+
8
+ Copyright (c) 2018 Preferred Networks, Inc.
9
+ Copyright (c) 2024 Kazuma NAITO.
10
+
11
+ Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ of this software and associated documentation files (the "Software"), to deal
13
+ in the Software without restriction, including without limitation the rights
14
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
+ copies of the Software, and to permit persons to whom the Software is
16
+ furnished to do so, subject to the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be included in all
19
+ copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27
+ SOFTWARE.
28
+
29
+
30
+ ** reference of [2] **
31
+ LEE, H., et al. Optimization subject to hidden constraints via statistical
32
+ emulation. Pacific Journal of Optimization, 2011, 7.3: 467-478
33
+
34
+
35
+
36
+ """
37
+
38
+
1
39
  from __future__ import annotations
2
40
 
3
41
  # ===== constant =====
@@ -1694,12 +1732,13 @@ class PoFBoTorchSampler(BaseSampler):
1694
1732
  else:
1695
1733
  running_params = None
1696
1734
 
1697
- if self._seed is not None:
1698
- random.seed(self._seed)
1699
- numpy.random.seed(self._seed)
1700
- torch.manual_seed(self._seed)
1701
- torch.backends.cudnn.benchmark = False
1702
- torch.backends.cudnn.deterministic = True
1735
+ # 一時的に取り消し:TPESampler と整合性が取れない
1736
+ # if self._seed is not None:
1737
+ # random.seed(self._seed)
1738
+ # numpy.random.seed(self._seed)
1739
+ # torch.manual_seed(self._seed)
1740
+ # torch.backends.cudnn.benchmark = False
1741
+ # torch.backends.cudnn.deterministic = True
1703
1742
 
1704
1743
  with manual_seed(self._seed):
1705
1744
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyfemtet
3
- Version: 0.6.0
3
+ Version: 0.6.2
4
4
  Summary: Design parameter optimization using Femtet.
5
5
  Home-page: https://github.com/pyfemtet/pyfemtet
6
6
  License: BSD-3-Clause
@@ -1,4 +1,4 @@
1
- pyfemtet/__init__.py,sha256=DS49q_bFynltwBtgneHYeVXTHLg5bjAOFWvTkv-jYmY,21
1
+ pyfemtet/__init__.py,sha256=d7NGuoje3vHyudKIFR_PmfKozIOKDFvAhGx0QXiyuMw,21
2
2
  pyfemtet/_message/1. make_pot.bat,sha256=oS38xYsaUnQAuKwUR8hZJFgt3AKBU993fWFDSg2ROz4,570
3
3
  pyfemtet/_message/2. make_mo.bat,sha256=nqUi3Cze7JGKkYItlch8ZG2gSbRNZiS2ltuCS7DbmG8,154
4
4
  pyfemtet/_message/__init__.py,sha256=gE1-XX_PzHj9BbhqPaK5VcIHuv6_Tec5qlPMC3IRiBg,100
@@ -13,8 +13,8 @@ pyfemtet/dispatch_extensions/_impl.py,sha256=HU7rKRAzEe5yYukWrKtdi1aIbUas_kLyaa_
13
13
  pyfemtet/logger/__init__.py,sha256=DZNTD9BboiFU9LOiyPKi_Y6gWAga5f1lWkVoq7LV_y0,71
14
14
  pyfemtet/logger/_impl.py,sha256=ZN5Rj3kb9UEGFt5KSLlzwfrLF_SAoOxgPBkadwh2Y8w,2825
15
15
  pyfemtet/opt/__init__.py,sha256=wRR8LbEhb5I6MUgmnCgjB6-tqHlOVxDIo7yPkq0QbBs,758
16
- pyfemtet/opt/_femopt.py,sha256=Yvcw4gFeWlDSor21RcwkaMZ7UedLKQuXKatqtyK8lWc,35341
17
- pyfemtet/opt/_femopt_core.py,sha256=NBIiELn6uno7dqoz_6oVAx-wnzkWYWmHaMJMj4rJUIM,31988
16
+ pyfemtet/opt/_femopt.py,sha256=v9qnH9e99nSFhxOwgkf45_i4f84SyV5ExfNr9fFgl6k,36666
17
+ pyfemtet/opt/_femopt_core.py,sha256=Sn13SI1r5OvSu6C9XjkqTrFz2IgO_vMszIAgA-gx-TU,34348
18
18
  pyfemtet/opt/_test_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
19
  pyfemtet/opt/_test_utils/control_femtet.py,sha256=Oy2MmNS-LhUXF9rKLa8AXAfJhppIQI8Nha8LmEZflmk,1169
20
20
  pyfemtet/opt/_test_utils/hyper_sphere.py,sha256=nQhw8EIY0DwvcTqrbKhkxiITLZifr4-nG77E-_6ggmA,700
@@ -28,12 +28,12 @@ pyfemtet/opt/interface/_femtet_with_nx/_interface.py,sha256=BXWdzIFcId1EovpbRD5D
28
28
  pyfemtet/opt/interface/_femtet_with_nx/update_model.py,sha256=P7VH0i_o-X9OUe6AGaLF1fACPeHNrMjcrOBCA3MMrI4,3092
29
29
  pyfemtet/opt/interface/_femtet_with_sldworks.py,sha256=NeNw1sqAL_kOrmrrcljrPwi_hBSA-LRU9MOqI_pjQXs,6836
30
30
  pyfemtet/opt/optimizer/__init__.py,sha256=Ia6viowECkG0IFXtFef0tJ4jDKsoDzJLqMJ9xLFH2LQ,543
31
- pyfemtet/opt/optimizer/_base.py,sha256=-gz7LPFv8v1dplMH796DMlh3O_VD32oHiTl6dlWXAlo,12148
31
+ pyfemtet/opt/optimizer/_base.py,sha256=-vfJ42GzofjVOB9-Cpf7J5fnuQ6fjZsAgozkMf1Ba6s,12147
32
32
  pyfemtet/opt/optimizer/_optuna/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
33
  pyfemtet/opt/optimizer/_optuna/_botorch_patch/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
34
  pyfemtet/opt/optimizer/_optuna/_botorch_patch/enable_nonlinear_constraint.py,sha256=2hUP2c8mokkRaSQ8nXxgCCmz8e0JKvEz8R2qIGnTGm0,8863
35
35
  pyfemtet/opt/optimizer/_optuna/_optuna.py,sha256=kdEi7N-ELWNgciD212h_afWFSO6kiRd960K9JJirVfc,16105
36
- pyfemtet/opt/optimizer/_optuna/_pof_botorch.py,sha256=so8BZqCTz2blfUB8JJnsfhInd__ZSiaf4P33VcdEzfw,71224
36
+ pyfemtet/opt/optimizer/_optuna/_pof_botorch.py,sha256=yVyg1V3trqirSDtbRepgftvS02AEkAhrgjou21JS124,72717
37
37
  pyfemtet/opt/optimizer/_scipy.py,sha256=_2whhMNq6hC1lr5PlYhpZ8Zlh6-DkAjz8SVB5qHIpYg,4766
38
38
  pyfemtet/opt/optimizer/_scipy_scalar.py,sha256=rGvrLjrgfYzxK9GA0-r2Hhoaqt6A0TQsT_1M3moyklc,3615
39
39
  pyfemtet/opt/optimizer/parameter.py,sha256=YLE9lmYRaZA8isnTPJnbYXpUn6zsJFW4xg03QaSWey8,3950
@@ -112,8 +112,8 @@ pyfemtet/opt/visualization/result_viewer/.gitignore,sha256=ryvb4aqbbsHireHWlPQfx
112
112
  pyfemtet/opt/visualization/result_viewer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
113
113
  pyfemtet/opt/visualization/result_viewer/application.py,sha256=WcHBx_J5eNLKSaprpk9BGifwhO04oN8FiNGYTWorrXA,1691
114
114
  pyfemtet/opt/visualization/result_viewer/pages.py,sha256=laEAKHAtdshCAHxgXo-zMNg3RP6lCxfszO3XwLnF1dU,32156
115
- pyfemtet-0.6.0.dist-info/LICENSE,sha256=sVQBhyoglGJUu65-BP3iR6ujORI6YgEU2Qm-V4fGlOA,1485
116
- pyfemtet-0.6.0.dist-info/METADATA,sha256=YKyoa4Ps_kcIy7x8PKI-zriuyGp3Z1NSCsdsOM9WgEA,3287
117
- pyfemtet-0.6.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
118
- pyfemtet-0.6.0.dist-info/entry_points.txt,sha256=ZfYqRaoiPtuWqFi2_msccyrVF0LurMn-IHlYamAegZo,104
119
- pyfemtet-0.6.0.dist-info/RECORD,,
115
+ pyfemtet-0.6.2.dist-info/LICENSE,sha256=sVQBhyoglGJUu65-BP3iR6ujORI6YgEU2Qm-V4fGlOA,1485
116
+ pyfemtet-0.6.2.dist-info/METADATA,sha256=e2iOiF_a7eF57VrVUBinZJQszajDEKS6RTzf0FNDJi0,3287
117
+ pyfemtet-0.6.2.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
118
+ pyfemtet-0.6.2.dist-info/entry_points.txt,sha256=ZfYqRaoiPtuWqFi2_msccyrVF0LurMn-IHlYamAegZo,104
119
+ pyfemtet-0.6.2.dist-info/RECORD,,