Coverage for C:\Users\t590r\Documents\GitHub\suppy\suppy\utils\plot.py: 0%

1 from itertools import cycle

2 import numpy as np

3

4 import numpy.typing as npt

5 import matplotlib.pyplot as plt

6

7

8 def plot2d_linear_constraints(x: npt.NDArray, A: npt.NDArray, lb: npt.NDArray, ub: npt.NDArray):

9 """

10 Plots the linear 2d constraints defined by lb <= A_0*x+A_1*y <= ub.

11

12 Parameters:

13 x (array-like): The x-values for the plot.

14 A (array-like): The coefficient matrix of the linear constraints.

15 lb (array-like): The lower bounds of the constraints.

16 ub (array-like): The upper bounds of the constraints.

17

18 Returns:

19 None

20 """

21 plt.figure()

22 ax = plt.gca()

23

24 color_cycle = cycle(plt.cm.tab10.colors)

25 for i in range(A.shape[0]):

26 color = next(color_cycle)

27 if A[i, 1] == 0:

28 ax.axvline(x=-lb[i] / A[i, 0], label=f"Constraint {i}", color=color)

29 ax.axvline(x=-ub[i] / A[i, 0], label=f"Constraint {i}", color=color)

30 else:

31 y = (lb[i] - A[i, 0] * x) / A[i, 1]

32 ax.plot(x, y, label=f"Constraint {i}", color=color)

33 y = (ub[i] - A[i, 0] * x) / A[i, 1]

34 ax.plot(x, y, label=f"Constraint {i}", color=color)

35 ax.set_ylim(-2, 2)

36 ax.legend()

37 return plt.gca()

38

39

40 def get_linear_constraint_bounds(x: npt.NDArray, A: npt.NDArray, lb: npt.NDArray, ub: npt.NDArray):

41 """

42 For a given 1D array x and linear constraints defined by lb <=

43 A_0*x+A_1*y <= ub, this function returns the associated y values.

44

45 Parameters:

46 x (npt.NDArray): Array-like object representing the x values.

47 A (npt.NDArray): Array-like object representing the coefficients of the linear constraints.

48 lb (npt.NDArray): Array-like object representing the lower bounds of the constraints.

49 ub (npt.NDArray): Array-like object representing the upper bounds of the constraints.

50

51 Returns:

52 x_all (npt.NDArray): Array-like object with size (len(x), len(lb)*2) storing all x values for all constraints (lower and upper bounds)

53 y_all (npt.NDArray): Array-like object storing all associated y values

54 """

55 y_l = (lb - A[:, 0] * x[:, None]) / A[

56 :, 1

57 ] # gives a nxm matrix with n = len(x) and m = len(lb)

58 y_u = (ub - A[:, 0] * x[:, None]) / A[:, 1]

59

60 x_all = np.tile(

61 x, (A.shape[0] * 2, 1)

62 ).T # get a x matrix that stores all x values for all constraints

63 return x_all, np.concatenate((y_l, y_u), axis=1)

64

65

66 def plot3d_linconstrained_function(func, A, x, lb, ub, func_args=()):

67 """

68 For given x values finds the associated y values (giving the linear

69 constrained bounds)

70 and plots the 2D surface of a function with linear constraints.

71

72 Parameters:

73 A (npt.NDArray): Array-like object representing the coefficients of the linear constraints.

74 x (npt.NDArray): Array-like object representing the x values.

75 lb (npt.NDArray): Array-like object representing the lower bounds of the constraints.

76 ub (npt.NDArray): Array-like object representing the upper bounds

77 """

78 x_1, x_2 = get_linear_constraint_bounds(x, A, lb, ub)

79

80 x_reshaped = np.reshape(

81 np.array([x_1, x_2]), (2, x_1.shape[0] * x_1.shape[1])

82 ) # reshape the array to be able to multiply with A

83 y = func(x_reshaped, *func_args).reshape(x_1.shape[0], x_1.shape[1])

84

85 fig = plt.figure()

86 ax = fig.add_subplot(111, projection="3d")

87

88 for i in range(x_1.shape[1]):

89 ax.plot(x_1[:, i], x_2[:, i], y[:, i], color="xkcd:black")

90

91 x_grid = np.linspace(np.min(x_1), np.max(x_1), 100)

92 y_grid = np.linspace(np.min(x_2), np.max(x_2), 100)

93 X, Y = np.meshgrid(x_grid, y_grid)

94 Z = func(np.array([X, Y]).reshape(2, -1)).reshape(X.shape[0], X.shape[1])

95 ax.plot_surface(X, Y, Z, cmap="plasma", alpha=0.2)

96 ax.set_xlabel("x$_1$")

97 ax.set_ylabel("x$_2$")

98 ax.set_xlim(np.min([np.min(x_1), np.min(x_2)]), np.max([np.max(x_1), np.max(x_2)]))

99 ax.set_ylim(np.min([np.min(x_1), np.min(x_2)]), np.max([np.max(x_1), np.max(x_2)]))

100 return fig, ax

101

102

103 def plot3d_general_objects(func, objects, func_args=(), x: None | npt.NDArray = None):

104 """PLots a 3D function with multiple objects."""

105 fig = plt.figure()

106 ax = fig.add_subplot(111, projection="3d")

107

108 for el in objects:

109 xy = el.get_xy() # should return a 2xn array

110 ax.plot(xy[0, :], xy[1, :], func(xy, *func_args), color="xkcd:black")

111

112 if x is None:

113 x = np.linspace(-10, 10, 100)

114

115 X, Y = np.meshgrid(x, x)

116 Z = func(np.array([X, Y]).reshape(2, -1), *func_args).reshape(X.shape[0], X.shape[1])

117 ax.plot_surface(X, Y, Z, cmap="plasma", alpha=0.2)

118

119 return fig, ax

120

121

122# if __name__ == "__main__":

123# #Importing some libraries

124# import numpy as np

125# import matplotlib.pyplot as plt

126# import suppy.projections as pr

127# import suppy.superiorization.sup as sup

128

129# center_1 = np.array([0,0])

130# radius = 1

131# center_2 = np.array([1,1])

132

133# center_3 = np.array([1.5,0])

134

135# #Creating a circle

136

137# Ball_1 = pr.Ball_Projection(center_1, radius)

138# Ball_2 = pr.Ball_Projection(center_2, radius)

139

140# def func_1(x):

141# return 1/len(x)*(x**2).sum(axis=0)

142

143# def grad_1(x):

144# return 1/len(x)*2*x

145

146# Proj = pr.Sequential_Projection([Ball_1,Ball_2])

147

148# Test = sup.Standard_superiorize(Proj,func_1,grad_1)

149

150# xF = Test.solve(np.array([1,3]),1,10,storage=True)

151# X = np.array(Test.all_X_values)

152

153# fig,ax = plot3d_generalObjects(func_1,[Ball_1,Ball_2],x=np.linspace(-3,3,50))

154# ax.plot(X[:,0],X[:,1],Test.all_function_values)

155# plt.show()