Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторная работа 4. 6 вар. Трофимов-2019.pdf
Скачиваний:
156
Добавлен:
19.02.2020
Размер:
135.31 Кб
Скачать

CТест реализации алгоритма Ньютона

1using System;

2using NUnit.Framework;

3

4namespace MathUtilities.Tests

5{

6

7

8

9

[TestFixture]

public class NewtonOptimizerTest

{

[Test]

10[TestCase(new double[]{0, 0}, new double[]{1, 1})]

11public void TestOptimal(double[] start, double[] expected)

12{

13

14

15

var op = new NewtonOptimizer(Function, start); var got = op.GetOptimal();

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

Assert.IsTrue(equals(got.items, expected));

}

[Test]

public void TestMatrixReverse()

{

var matrixAsArray = new double[2][]; matrixAsArray[0] = new double[]{0.5, 1}; matrixAsArray[1] = new double[]{2, 2};

var expectedMatrixAsArray = new double[2][]; expectedMatrixAsArray[0] = new double[]{-2, 1}; expectedMatrixAsArray[1] = new double[]{2, -0.5}; var matrix = new Matrix(matrixAsArray);

var got = matrix.GetReversed();

var expected = new Matrix(expectedMatrixAsArray);

32

33

34

35

36

37

38

39

40

41

42

43

44

45

var gotArray = TwoDimensionalIntoOneDimensional(got.items);

var expectedArray = TwoDimensionalIntoOneDimensional(expected.items);

Assert.IsTrue(equals(gotArray, expectedArray));

}

[Test]

public void TestMatrixAction()

{

var matrixAsArray = new double[3][]; matrixAsArray[0] = new double[]{2, 4, 0}; matrixAsArray[1] = new double[]{-2, 1, 3}; matrixAsArray[2] = new double[]{-1, 0, 1};

21

46

47

48

var matrix = new Matrix(matrixAsArray); var vector = new Vector(1, 2, -1);

49

var got = matrix * vector;

50

var expected = new Vector(10, -3, -2);

51

Assert.IsTrue(equals(got.items, expected.items));

52

}

53

54[Test]

55[TestCase(new double[]{1, 1}, 0, 0)]

56[TestCase(new double[]{0, 0}, -200, 0)]

57public void TestAnotherFunctionPartial(double[] arr, double expected1, ,! double expected2)

58{

59

var a = new Derivative(Function);

60

var partial1 = a.GetPartialDerivative(new Vector(arr), 0);

61

var partial2 = a.GetPartialDerivative(new Vector(arr), 1);

62

Assert.IsTrue(equals(partial1, expected1));

63

Assert.IsTrue(equals(partial2, expected2));

64

}

65

66[Test]

67[TestCase(new double[]{0, 0}, 0)]

68[TestCase(new double[]{1, 1}, 2)]

69public void TestPartial1(double[] arr, double expected)

70{

71

72

73

var a = new Derivative(TypicalFunction);

var partial1 = a.GetPartialDerivative(new Vector(arr), 0);

74

Assert.IsTrue(equals(expected, partial1));

75

}

76

77[Test]

78[TestCase(new double[]{0, 0}, 0)]

79[TestCase(new double[]{1, 1}, 2)]

80public void TestPartial2(double[] arr, double expected)

81{

82

83

var a = new Derivative(TypicalFunction);

var partial2 = a.GetPartialDerivative(new Vector(arr), 1);

84

 

85

Assert.IsTrue(equals(expected, partial2));

86

}

87

88[Test]

89[TestCase(new double[]{0, 0}, new double[]{0, 0})]

90[TestCase(new double[]{1, 1}, new double[]{2, 2})]

91public void TestGradient(double[] arr, double[] expected)

22

92

93

94

95

96

97

98

{

var a = new Derivative(TypicalFunction);

var gradient = a.GetGradient(new Vector(arr));

Assert.IsTrue(equals(gradient, new Vector(expected)));

}

99[Test]

100[TestCase(new double[]{0, 0}, new double[]{2, 0, 0, 2})]

101[TestCase(new double[]{1, 1}, new double[]{2, 0, 0, 2})]

102public void TestSecondPartial(double[] arr, double[] expected)

103{

104

105

var array = new double[4];

106

var a = new Derivative(TypicalFunction);

107

for (int i = 0; i < 2; i++)

108

for (int j = 0; j < 2; j++)

109

array[2 * i + j] = a.GetSecondPartialDerivative(new

 

,! Vector(arr), i, j);

110

 

111

Assert.IsTrue(equals(array, expected));

112

}

113

 

114[Test]

115[TestCase(new double[]{0, 0}, new double[] {2, 0, 0, 2})]

116[TestCase(new double[]{1, 1}, new double[] {2, 0, 0, 2})]

117public void TestHessian(double[] arr, double[] expected)

118{

119

var

a = new Derivative(TypicalFunction);

120

var

hessian = a.GetHessian(new Vector(arr));

121

var

oneDimensionalHessian =

 

,!

TwoDimensionalIntoOneDimensional(hessian.items);

122

 

 

123

Assert.IsTrue(equals(oneDimensionalHessian, expected));

124

}

 

125

 

 

126/// <summary>

127/// x^2 + y^2

128/// </summary>

129/// <remark>

130/// F'(0, 0) = 0;

131/// F'(1, 1) = 2;

132/// </remark>

133private double TypicalFunction(Vector vector) =>

134 Math.Pow(vector.Get(0), 2) + Math.Pow(vector.Get(1), 2);

135

136

23

137/// <summary>

138/// (x_2 - x_1^2)^2 + 100 * (1 - x_1)^2

139/// </summary>

140private static double Function(Vector vector) =>

141

Math.Pow(vector.Get(1) - Math.Pow(vector.Get(0), 2), 2) + 100 *

 

,! Math.Pow(1 - vector.Get(0), 2);

142

143/// <summary>

144/// Переводит двумерный массив в длинный одномерный.

145/// </summary>

146/// <param name="arr">двумерный массив</param>

147/// <returns>одномерный массив, ячейки строк идут друг за ,! другом</returns>

148private double[] TwoDimensionalIntoOneDimensional(double[][] arr)

149{

150

151

152

153

154

155

156

157

158

159

160

161

162

var length = (int) arr.Length;

var answerLength = (int) Math.Pow(length, 2); var answer = new double[answerLength];

for (var i = 0; i < length; i++) for (var j = 0; j < length; j++)

answer[2 * i + j] = arr[i][j];

return answer;

}

private bool equals(Vector vec1, Vector vec2) => equals(vec1.items, vec2.items);

163/// <summary>

164/// Примерно сравнивает массивы.

165/// Последовательно использует функцию примерного сравнивания чисел.

166/// </summary>

167/// <param name="arr1">первый массив</param>

168/// <param name="arr2">второй массив</param>

169/// <returns>истина, если массивы примерно равны</returns>

170private bool equals(double[] arr1, double[] arr2)

171{

172

173

174

175

for (var i = 0; i < arr1.Length; i++) if (!equals(arr1[i], arr2[i]))

return false;

176

return true;

177

}

178

 

179

180

181

///<summary>

///Примерно сравнивает числа.

///</summary>

24

182/// <param name="a">первое число</param>

183/// <param name="b">второе число</param>

184/// <returns>истина, если числа равны хотя бы на [TYPICAL_PRECISION] ,! порядков</returns>

185private bool equals(double a, double b)

186{

187

var

eq = Math.Max(Infinitesimal.GetPrecision(a),

 

,!

Infinitesimal.GetPrecision(b));

188

if (Math.Abs(a - b) < eq)

189

 

return true;

190

 

 

191

return false;

192}

193}

194}

25