13.5. GTDoE

13.5.1. example_gtdoe.py

  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
#
# coding: utf-8
# Copyright (C) pSeven SAS, 2010-present
#


from da.p7core import gtdoe
from da.p7core.loggers import StreamLogger

import random

def batch():
  """Example of GTDoE usage."""
  print('\nPython batch DoE example:')
  print('=' * 60)
  # prepare data
  number = 50
  iDim = 3
  random.seed(100)
  lb = [random.uniform(0, 1) for _ in range(iDim)]
  ub = [2 + random.uniform(0, 1) for _ in range(iDim)]

  # create generator
  generator = gtdoe.Generator()
  # set logger
  generator.set_logger(StreamLogger())

  # set options
  options = {
    'GTDoE/Technique': 'OLHS',
    'GTDoE/Deterministic': 'yes',
    'GTDoE/LogLevel': 'Debug'
  }
  generator.options.set(options)

  # get result
  result = generator.generate(bounds=(lb, ub), count=number)

  # result if finite point generator, can get all points
  points = result.points
  number = len(points) # may be less than initial
  toShow = min(number // 10, 10)
  print('\nResults:')
  print('-' * 60)
  maxlen = 0
  for i, s in enumerate(points[:toShow]):
    p = '[%3d]: %s' % ((i + 1), s)
    maxlen = max(len(p), maxlen)
    print(str(p))
  print('      %s' % ('.' * (maxlen - 7)))
  for i, s in enumerate(points[-toShow:]):
    print('[%3d]: %s' % ((number - toShow + i + 1), s))
  print('Info:')
  print(str(result))
  print('-' * 60)

  print('    PhiP metric for generated set: %s' % gtdoe.measures.phi_p((lb, ub), points))
  print('      Potential for generated set: %s' % gtdoe.measures.potential((lb, ub), points))
  print(' Minimax metric for generated set: %s' % gtdoe.measures.minimax_distance((lb, ub), points))
  print('-' * 60)

def sequential():
  """Example of GTDoE usage."""
  print('\nPython sequential DoE example:')
  print('=' * 60)
  number = 50
  iDim = 3
  generator = gtdoe.Generator()
  generator.set_logger(StreamLogger())

  random.seed(100)
  lb = [random.uniform(0, 1) for _ in range(iDim)]
  ub = [2 + random.uniform(0, 1) for _ in range(iDim)]

  result = generator.generate(bounds=(lb, ub))
  # result is infinite points generator
  # take first 50 points
  points = result.take(number)
  toShow = min(number // 10, 10)
  print('\nResults:')
  print('-' * 60)
  maxlen = 0
  for i, s in enumerate(points[:toShow]):
    p = '[%3d]: %s' % ((i + 1), s)
    maxlen = max(len(p), maxlen)
    print(str(p))
  print('      %s' % ('.' * (maxlen - 7)))
  for i, s in enumerate(points[-toShow:]):
    print('[%3d]: %s' % ((number - toShow + i + 1), s))
  print('Info:')
  print(str(result))
  print('-' * 60)

  print('    PhiP metric for generated set: %s' % gtdoe.measures.phi_p((lb, ub), points))
  print('      Potential for generated set: %s' % gtdoe.measures.potential((lb, ub), points))
  print(' Minimax metric for generated set: %s' % gtdoe.measures.minimax_distance((lb, ub), points))
  print('-' * 60)

if __name__ == "__main__":
  batch()
  sequential()

  # oneliner
  for k in gtdoe.Generator().generate(count=10, bounds=([0,0], [10,100]), options={'GTDOE/LogLevel': 'Debug'}):
    print(['%05.2f' % i for i in k])

13.5.2. example_gtdoe_multidim_factors.py

 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
#
# coding: utf-8
# Copyright (C) pSeven SAS, 2010-present
#


"""
Example of Full Factorial GTDoE with multidimensional factors.
"""

import itertools
import numpy as np
from da.p7core import gtdoe

def main():
  generator = gtdoe.Generator()
  factors_doe = []
  # factor 1 (2-dimensional, with SobolSeq DoE)
  doe_result = generator.generate(count=3, bounds=([0, 0], [1, 1]),
                                  options={'GTDoE/Technique': 'SobolSeq'})
  factors_doe.append(doe_result.points)
  # factor 2 (2-dimensional, with LHS DoE)
  doe_result = generator.generate(count=2, bounds=([0, 0], [1, 1]),
                                  options={'GTDoE/Technique': 'LHS'})
  factors_doe.append(doe_result.points)
  # factor 3 (1-dimensional, just two points)
  doe = np.array([0, 1])[:, np.newaxis]
  # newaxis is used since it's important to have two-dimensional array
  factors_doe.append(doe)

  for (count, factor_doe) in enumerate(factors_doe):
    print('Factor %i' % count)
    print(str(factor_doe))
    print('')

  try:
    # calculate Cartesian product using itertools.product
    ta_doe = np.array([np.hstack(x_i) for x_i in itertools.product(*factors_doe)])
  except AttributeError:
    # manual Cartesian product
    ta_doe = factors_doe[-1]
    for factor_data in factors_doe[-2::-1]:
      ta_doe = np.hstack((np.repeat(factor_data, ta_doe.shape[0], axis=0), \
                              np.tile(ta_doe, (factor_data.shape[0], 1))))

  print('Generated Full Factorial DoE with multidimensional factors')
  print(ta_doe)

if __name__ == "__main__":
  main()

13.5.3. example_gtdoe_adaptive_grid.py

 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
#
# coding: utf-8
# Copyright (C) pSeven SAS, 2010-present
#

"""
Example: how to use adaptive design of experiments on a grid.
"""

import os

import numpy as np
import matplotlib.pyplot as plt

from da.p7core import gtapprox, gtdoe
from da.p7core.blackbox import Blackbox
from da.p7core.loggers import StreamLogger, LogLevel

class UserBlackbox(Blackbox):
  def prepare_blackbox(self):
    """Required blackbox method. Defines design variables and responses."""
    self.add_variable(bounds=(0, 1))
    self.add_variable(bounds=(0, 1))
    self.add_response()

  def evaluate(self, design_points):
    """Required blackbox method. Returns an array of function values."""
    result = []
    for design_point in design_points:
      x, y = design_point
      result.append((x + 1)**2 + (y - 1)**2)
    return result

def main():
  budget = 30
  generator = gtdoe.Generator()
  generator.set_logger(StreamLogger())
  bbox = UserBlackbox()
  # We define levels as evenly distributed values in some interval
  #
  # Note that some levels are outside of generation bounds. They will be ignored during the generation.
  levels_x = np.linspace(0, 1, 20).tolist()
  levels_y = np.linspace(0, 1.1, 10).tolist()
  # To generate adaptive design on a grid instead of continous space, we need to set only one option
  generator.options.set({
    "GTDoE/CategoricalVariables": [0, levels_x, 1, levels_y]
  })
  # As blackbox is provided, adaptive mode will be selected automatically
  result = generator.generate(bounds=bbox.variables_bounds(), budget=budget, blackbox=bbox)

  # Plot the results
  xx, yy = np.meshgrid(levels_x, levels_y)
  plt.plot(xx.ravel(), yy.ravel(), 'ko', label="Grid levels")
  plt.plot(result.points[:, 0], result.points[:, 1], 'rs', label="Selected points")
  plt.title("Adaptive DoE on grid")
  plt.xlabel("$x$", fontsize ="16")
  plt.ylabel("$y$", fontsize ="16")
  plt.legend()
  plt.xlim(-.1, 1.2)
  plt.ylim(-.1, 1.2)

  # Show plots if we may.
  if 'SUPPRESS_SHOW_PLOTS' not in os.environ:
    print("Close plot windows to finish.")
    plt.show()


if __name__ == "__main__":
  main()

13.5.4. example_gtdoe_levels.py

 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
#
# coding: utf-8
# Copyright (C) pSeven SAS, 2010-present
#


"""
Example of GTDoE usage with levels.
"""

from da.p7core import gtdoe

def main():
  print('\nExample of DoE with levels:\n')
  print('=' * 60)

  generator = gtdoe.Generator()

  # factors 0 and 2 are leveled
  levels = [0, [0.3, 1.1, 2.4, 2.8], 2, [1.2, 1.6, 2.9]]

  # set design space bounds
  # note that despite the two factors above are leveled,
  # we still need to specify bounds for all factors since it is
  # the only way to set the design space dimension
  lower = [0, 0, 0, 0, 0]
  upper = [3, 3, 3, 3, 3]

  # set options
  options = {
    'GTDoE/Technique': 'LHS',
    'GTDoE/CategoricalVariables': levels  # specifies factor levels
  }
  generator.options.set(options)

  # get result
  result = generator.generate(bounds=(lower, upper), count=50)

  # show result
  points = result.points
  number = len(points) # may be less than initial
  toShow = min(number // 10, 10)
  print('\nResults:')
  print('-' * 60)
  maxlen = 0
  for i, s in enumerate(points[:toShow]):
    s = [round(value, 4) for value in s]
    p = '[%3d]: %s' % ((i + 1), s)
    maxlen = max(len(p), maxlen)
    print(str(p))
  print('      %s' % ('.' * (maxlen - 7)))
  for i, s in enumerate(points[-toShow:]):
    s = [round(value, 4) for value in s]
    print('[%3d]: %s' % ((number - toShow + i + 1), s))
  print('Info:')
  print(str(result))

if __name__ == "__main__":
  main()