DryChem 1.0.0
A generic, compile-time C++ toolbox with no dependencies for the modern computational chemistry project.
Loading...
Searching...
No Matches
testDifferentiationMethods.hpp
Go to the documentation of this file.
1// Copyright (c) 2020-2025 Cody R. Drisko. All rights reserved.
2// Licensed under the MIT License. See the LICENSE file in the project root for more information.
3//
4// Name: testDifferentiationMethods.hpp
5// Author: crdrisko
6// Date: 10/28/2020-07:58:23
7// Description: Provides ~100% unit test coverage over the approximate differentiation methods
8
9#ifndef DRYCHEM_COMMON_UTILITIES_LIBS_MATH_TESTS_TESTCALCULUS_TESTDIFFERENTIATIONMETHODS_HPP
10#define DRYCHEM_COMMON_UTILITIES_LIBS_MATH_TESTS_TESTCALCULUS_TESTDIFFERENTIATIONMETHODS_HPP
11
12#include <cstddef>
13#include <sstream>
14#include <vector>
15
16#include <common-utils/math.hpp>
17#include <gtest/gtest.h>
18
19GTEST_TEST(testDifferentiationMethods, forwardDifferenceMethodReturnsAVectorWithASizeOneLessThanTheInputs)
20{
21 std::vector<long double> x, y, expectedResult;
22
23 for (std::size_t i {}; i <= 10; ++i)
24 {
25 x.push_back(static_cast<long double>(i));
26 y.push_back(static_cast<long double>(i));
27
28 expectedResult.push_back((x[i] * x[i]) / 2.0);
29 }
30
31 // Actual: d/dx (x) = 1
32 std::vector<long double> forwardFDM1(10, 1.0);
33 auto forwardResult1 = DryChem::forwardDifferenceMethod(x, y);
34
35 ASSERT_EQ(forwardFDM1, forwardResult1);
36
37 // Actual: d/dx (1/2 x^2) = x
38 std::vector<long double> forwardFDM2 {0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5};
39 auto forwardResult2 = DryChem::forwardDifferenceMethod(x.begin(), x.end(), expectedResult.begin(), expectedResult.end());
40
41 ASSERT_EQ(forwardFDM2, forwardResult2);
42}
43
44GTEST_TEST(testDifferentiationMethods, backwardsDifferenceMethodReturnsAVectorWithASizeOneLessThanTheInputs)
45{
46 std::vector<long double> x, y, expectedResult;
47
48 for (std::size_t i {}; i <= 10; ++i)
49 {
50 x.push_back(static_cast<long double>(i));
51 y.push_back(static_cast<long double>(i));
52
53 expectedResult.push_back((x[i] * x[i]) / 2.0);
54 }
55
56 // Actual: d/dx (x) = 1
57 std::vector<long double> backwardsFDM1(10, 1.0);
58 auto backwardsResult1 = DryChem::backwardsDifferenceMethod(x, y);
59
60 ASSERT_EQ(backwardsFDM1, backwardsResult1);
61
62 // Actual: d/dx (1/2 x^2) = x
63 std::vector<long double> backwardsFDM2 {0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5};
64 auto backwardsResult2
65 = DryChem::backwardsDifferenceMethod(x.begin(), x.end(), expectedResult.begin(), expectedResult.end());
66
67 ASSERT_EQ(backwardsFDM2, backwardsResult2);
68}
69
70GTEST_TEST(testDifferentiationMethods, defaultCenteredDifferenceMethodReturnsAVectorWithASizeEqualToThatOfTheInputs)
71{
72 std::vector<long double> x, y, expectedResult;
73
74 for (std::size_t i {}; i <= 10; ++i)
75 {
76 x.push_back(static_cast<long double>(i));
77 y.push_back(static_cast<long double>(i));
78 expectedResult.push_back((x[i] * x[i]) / 2.0);
79 }
80
81 // Actual: d/dx (x) = 1
82 std::vector<long double> centeredFDM1(11, 1.0);
83 auto centeredResult1 = DryChem::centeredDifferenceMethod(x, y);
84
85 ASSERT_EQ(centeredFDM1, centeredResult1);
86
87 // Actual: d/dx (1/2 x^2) = x
88 std::vector<long double> centeredFDM2 {0.5, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 9.5};
89 auto centeredResult2
90 = DryChem::centeredDifferenceMethod(x.begin(), x.end(), expectedResult.begin(), expectedResult.end());
91
92 ASSERT_EQ(centeredFDM2, centeredResult2);
93}
94
95GTEST_TEST(testDifferentiationMethods, nonDefaultCenteredDifferenceMethodReturnsAVectorWithASizeTwoLessThanTheInputs)
96{
97 std::vector<long double> x, y, expectedResult;
98
99 for (std::size_t i {}; i <= 10; ++i)
100 {
101 x.push_back(static_cast<long double>(i));
102 y.push_back(static_cast<long double>(i));
103 expectedResult.push_back((x[i] * x[i]) / 2.0);
104 }
105
106 // Actual: d/dx (x) = 1
107 std::vector<long double> centeredFDM1(9, 1.0);
108 auto centeredResult1 = DryChem::centeredDifferenceMethod(x, y, false);
109
110 ASSERT_EQ(centeredFDM1, centeredResult1);
111
112 // Actual: d/dx (1/2 x^2) = x
113 std::vector<long double> centeredFDM2 {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0};
114 auto centeredResult2
115 = DryChem::centeredDifferenceMethod(x.begin(), x.end(), expectedResult.begin(), expectedResult.end(), false);
116
117 ASSERT_EQ(centeredFDM2, centeredResult2);
118}
119
120GTEST_TEST(testDifferentiationMethods, passingTwoDifferentlySizedContainersResultsInFatalException)
121{
122 std::stringstream deathRegex;
123
124 deathRegex << "Common-Utilities Fatal Error: ";
125
126#if GTEST_USES_POSIX_RE
127 deathRegex << "[(](forward|backwards|centered)DifferenceMethod.hpp: *[0-9]*[)]\n\t";
128#elif GTEST_USES_SIMPLE_RE
129 deathRegex << "\\(\\S*DifferenceMethod.hpp: \\d*\\)\n\t";
130#endif
131
132 deathRegex << "Input sizes for x and y containers must be the same.\n";
133
134 std::vector<long double> x {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0};
135 std::vector<long double> y {2.0, 5.0, 3.0, 7.0, 8.0, 9.0, 12.0, 10.0, 15.0, 20.0};
136
137 ASSERT_DEATH(
138 {
139 try
140 {
141 DryChem::forwardDifferenceMethod(x.begin(), x.end(), y.begin(), y.end() - 2);
142 }
143 catch (const DryChem::InputSizeMismatch& except)
144 {
145 except.handleErrorWithMessage();
146 }
147 },
148 deathRegex.str());
149
150 ASSERT_DEATH(
151 {
152 try
153 {
154 DryChem::backwardsDifferenceMethod(x.begin(), x.end(), y.begin(), y.end() - 2);
155 }
156 catch (const DryChem::InputSizeMismatch& except)
157 {
158 except.handleErrorWithMessage();
159 }
160 },
161 deathRegex.str());
162
163 ASSERT_DEATH(
164 {
165 try
166 {
167 DryChem::centeredDifferenceMethod(x.begin(), x.end(), y.begin(), y.end() - 2);
168 }
169 catch (const DryChem::InputSizeMismatch& except)
170 {
171 except.handleErrorWithMessage();
172 }
173 },
174 deathRegex.str());
175}
176
177#endif
GTEST_TEST(testDifferentiationMethods, forwardDifferenceMethodReturnsAVectorWithASizeOneLessThanTheInputs)
Definition testDifferentiationMethods.hpp:19