Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

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

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

from __future__ import division 

from builtins import zip 

from builtins import range 

import numpy as np 

from gpkit import Variable, Model 

import scipy.optimize as op 

 

import unittest 

from gpkit.tests.helpers import run_tests 

 

from robust.linearize_twoterm_posynomials import LinearizeTwoTermPosynomials 

 

np.warnings.filterwarnings('ignore') 

 

def convex_function(x): 

return np.log(1 + np.exp(x)) 

 

class TestLinearization(unittest.TestCase): 

def test_tangent_point_func(self): 

for _ in range(100): 

eps = np.random.rand() * 0.2 

x_old = - np.random.rand() * np.log(np.exp(0.2) - 1) 

y_old = convex_function(x_old) - eps 

x_tangent = op.newton(LinearizeTwoTermPosynomials.tangent_point_func, x_old + 1, args=(x_old, eps)) 

y_tangent = convex_function(x_tangent) 

 

self.assertGreater(x_tangent, x_old) 

 

def tangent_line(x): 

return (y_old - y_tangent) * (x - x_tangent) / (x_old - x_tangent) + y_tangent 

 

self.assertLess(convex_function(x_tangent) - tangent_line(x_tangent), 0.0001) 

 

trial_points = list(np.arange(0, 20, 0.01)) 

function_points = [convex_function(i) for i in trial_points] 

tangent_points = [tangent_line(i) for i in trial_points] 

difference = [a - b for a, b in zip(function_points, tangent_points)] 

 

self.assertTrue(all(i >= 0 for i in difference)) 

 

return 

 

 

def test_intersection_point_function(self): 

for _ in range(100): 

eps = np.random.rand() * 0.2 

x_old = - np.random.rand() * np.log(np.exp(0.2) - 1) 

y_old = convex_function(x_old) - eps 

 

x_tangent = op.newton(LinearizeTwoTermPosynomials.tangent_point_func, x_old + 1, args=(x_old, eps)) 

y_tangent = convex_function(x_tangent) 

 

tangent_slope = (y_old - y_tangent) / (x_old - x_tangent) 

tangent_intercept = - (y_old - y_tangent) * x_tangent / (x_old - x_tangent) + y_tangent 

 

x_intersection = op.newton(LinearizeTwoTermPosynomials.intersection_point_func, 

x_tangent + 1, args=(tangent_slope, tangent_intercept, eps)) 

self.assertGreater(x_intersection, x_tangent) 

 

diff = convex_function(x_intersection) - eps - tangent_slope * x_intersection - tangent_intercept 

 

self.assertLess(diff, 0.0001) 

return 

 

 

def test_iterate_two_term_posynomial_linearization_coeff(self): 

# Passes... 

for _ in range(10): 

 

eps = np.random.rand() * np.log(2) 

r = int(np.ceil(np.random.rand()*18)) + 1 

 

number_of_actual_r, a, b, x_tangent, x_intersection = LinearizeTwoTermPosynomials.iterate_two_term_posynomial_linearization_coeff(r, eps) 

 

def piece_wise_linear_function(x): 

evaluations = [a_i*x + b_i for a_i, b_i in zip(a, b)] 

evaluations.insert(0, 0) 

evaluations.append(x) 

return max(evaluations) 

 

# raise Exception("ejer") 

tangent_difference = [convex_function(k) - piece_wise_linear_function(k) for k in x_tangent] 

intersection_difference = [convex_function(k) - piece_wise_linear_function(k) for k in x_intersection] 

 

self.assertTrue(all(i <= 0.00001 for i in tangent_difference)) 

self.assertTrue(all(i - eps <= 0.00001 for i in intersection_difference)) 

 

def test_two_term_posynomial_linearization_coeff(self): 

for r in range(3, 21): 

 

slopes, intercepts, x_tangent, x_intersection, eps = LinearizeTwoTermPosynomials.\ 

two_term_posynomial_linearization_coeff(r) 

 

self.assertTrue(all(np.abs(slopes[i] + slopes[r - i - 3] - 1) <= 0.0001 for i in range(0, r-2))) 

self.assertTrue(all(np.abs(intercepts[i] - intercepts[r - i - 3]) <= 0.001 for i in range(0, r-2))) 

 

def piece_wise_linear_function(x): 

evaluations = [a_i*x + b_i for a_i, b_i in zip(slopes, intercepts)] 

evaluations.insert(0, 0) 

evaluations.append(x) 

return max(evaluations) 

 

tangent_difference = [convex_function(k) - piece_wise_linear_function(k) for k in x_tangent] 

intersection_difference = [convex_function(k) - piece_wise_linear_function(k) for k in x_intersection] 

 

self.assertTrue(all(i <= 0.001 for i in tangent_difference)) 

self.assertTrue(all(np.abs(i - eps) <= 0.001 for i in intersection_difference)) 

 

def test_linearize_two_term_posynomial(self): 

for _ in range(20): 

tol = np.random.rand()*0.001 

number_of_gp_variables = int(np.random.rand()*20) + 1 

 

m_1 = np.random.rand()*10 

m_2 = np.random.rand()*10 

subs = {} 

for i in range(number_of_gp_variables): 

x = Variable('x_%s' % i) 

m_1 *= x**(np.random.rand()*10 - 5) 

m_2 *= x**(np.random.rand()*10 - 5) 

subs[x.key.name] = np.random.rand()*100 

 

p = m_1 + m_2 

 

r = int(np.random.rand()*18) + 2 

linearized_p = LinearizeTwoTermPosynomials(p) 

no_data_upper, no_data_lower, data = linearized_p.linearize_two_term_posynomial(1, r) 

 

self.assertEqual(len(data), r) 

self.assertEqual(len(no_data_upper), 1) 

self.assertEqual(len(no_data_lower), 1) 

 

subs_p = p.sub(subs) 

m = Model(Variable("w_1"), data, subs) 

sol = m.solve(verbosity=0) 

w_1 = sol['cost'] 

 

upper_pos = no_data_upper[0].as_posyslt1() 

lower_pos = no_data_lower[0].as_posyslt1() 

 

upper_over_lower = upper_pos[0]/lower_pos[0] 

eps = np.log(upper_over_lower.cs[0]) 

 

self.assertTrue(np.log(subs_p.cs[0]) - np.log(lower_pos[0].sub({"w_1": w_1}).cs[0]) <= eps + tol) 

self.assertTrue(np.log(upper_pos[0].sub({"w_1": w_1}).cs[0]) - np.log(subs_p.cs[0]) <= eps + tol) 

 

TESTS = [TestLinearization] 

 

def test(): 

run_tests(TESTS) 

 

if __name__ == "__main__": 

test()