forked from arjendeetman/GCMMA-MMA-Python
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmma_function.py
More file actions
119 lines (93 loc) · 3.55 KB
/
Copy pathmma_function.py
File metadata and controls
119 lines (93 loc) · 3.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# SPDX-License-Identifier: GPL-3.0-or-later
"""
GCMMA-MMA-Python
This file is part of GCMMA-MMA-Python. GCMMA-MMA-Python is licensed under the terms of GNU
General Public License as published by the Free Software Foundation. For more information and
the LICENSE file, see <https://github.com/arjendeetman/GCMMA-MMA-Python>.
The orginal work is written by Krister Svanberg in MATLAB. This is the Python implementation
of the code written by Arjen Deetman.
Optimization of a simple function with one design variable and no constraint functions.
Minimize:
(x - 50)^2 + 25
Subject to:
1 <= x <= 100
"""
# Loading modules
from __future__ import division
from mmapy import mmasub, kktcheck
from util import setup_logger
from typing import Tuple
import numpy as np
import os
def main() -> None:
# Logger
path = os.path.dirname(os.path.realpath(__file__))
file = os.path.join(path, "mma_function.log")
logger = setup_logger(file)
logger.info("Started\n")
# Set numpy print options
np.set_printoptions(precision=4, formatter={'float': '{: 0.4f}'.format})
# Initial settings
m, n = 1, 1
eeen = np.ones((n, 1))
eeem = np.ones((m, 1))
zeron = np.zeros((n, 1))
zerom = np.zeros((m, 1))
xval = 1 * eeen
xold1 = xval.copy()
xold2 = xval.copy()
xmin = eeen.copy()
xmax = 100 * eeen
low = xmin.copy()
upp = xmax.copy()
move = 1.0
c = 1000 * eeem
d = eeem.copy()
a0 = 1
a = zerom.copy()
innerit = 0
outeriter = 0
maxoutit = 20
kkttol = 0
# Calculate function values and gradients of the objective and constraints functions
if outeriter == 0:
f0val, df0dx, fval, dfdx = funct(xval, n, eeen, zeron)
outvector1 = np.array([outeriter, innerit, f0val, fval])
outvector2 = xval.flatten()
# Log
logger.info("outvector1 = {}".format(outvector1))
logger.info("outvector2 = {}\n".format(outvector2))
# The iterations start
kktnorm = kkttol + 10
outit = 0
while kktnorm > kkttol and outit < maxoutit:
outit += 1
outeriter += 1
# The MMA subproblem is solved at the point xval:
xmma, ymma, zmma, lam, xsi, eta, mu, zet, s, low, upp = mmasub(
m, n, outeriter, xval, xmin, xmax, xold1, xold2, f0val, df0dx, fval, dfdx, low, upp, a0, a, c, d, move)
# Some vectors are updated:
xold2 = xold1.copy()
xold1 = xval.copy()
xval = xmma.copy()
# Re-calculate function values and gradients of the objective and constraints functions
f0val, df0dx, fval, dfdx = funct(xval, n, eeen, zeron)
# The residual vector of the KKT conditions is calculated
residu, kktnorm, residumax = kktcheck(
m, n, xmma, ymma, zmma, lam, xsi, eta, mu, zet, s, xmin, xmax, df0dx, fval, dfdx, a0, a, c, d)
outvector1 = np.array([outeriter, innerit, f0val, fval])
outvector2 = xval.flatten()
# Log
logger.info("outvector1 = {}".format(outvector1))
logger.info("outvector2 = {}".format(outvector2))
logger.info("kktnorm = {}\n".format(kktnorm))
# Final log
logger.info("Finished")
def funct(xval: np.ndarray, n: int, eeen: np.ndarray, zeron: np.ndarray) -> Tuple[float, np.ndarray, float, np.ndarray]:
f0val = (xval.item() - 50) ** 2 + 25
df0dx = eeen * (2 * (xval.item() - 50))
fval = 0.0
dfdx = zeron
return f0val, df0dx, fval, dfdx
if __name__ == "__main__":
main()