1 // ******************************************************************************
2 //
3 // Title: Force Field X.
4 // Description: Force Field X - Software for Molecular Biophysics.
5 // Copyright: Copyright (c) Michael J. Schnieders 2001-2025.
6 //
7 // This file is part of Force Field X.
8 //
9 // Force Field X is free software; you can redistribute it and/or modify it
10 // under the terms of the GNU General Public License version 3 as published by
11 // the Free Software Foundation.
12 //
13 // Force Field X is distributed in the hope that it will be useful, but WITHOUT
14 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16 // details.
17 //
18 // You should have received a copy of the GNU General Public License along with
19 // Force Field X; if not, write to the Free Software Foundation, Inc., 59 Temple
20 // Place, Suite 330, Boston, MA 02111-1307 USA
21 //
22 // Linking this library statically or dynamically with other modules is making a
23 // combined work based on this library. Thus, the terms and conditions of the
24 // GNU General Public License cover the whole combination.
25 //
26 // As a special exception, the copyright holders of this library give you
27 // permission to link this library with independent modules to produce an
28 // executable, regardless of the license terms of these independent modules, and
29 // to copy and distribute the resulting executable under terms of your choice,
30 // provided that you also meet, for each linked independent module, the terms
31 // and conditions of the license of that module. An independent module is a
32 // module which is not derived from or based on this library. If you modify this
33 // library, you may extend this exception to your version of the library, but
34 // you are not obligated to do so. If you do not wish to do so, delete this
35 // exception statement from your version.
36 //
37 // ******************************************************************************
38 package ffx.numerics.integrate;
39
40 import static ffx.numerics.integrate.Integration.generateTestData_v1;
41 import static ffx.numerics.integrate.Integration.halfBinComposite;
42 import static ffx.numerics.integrate.Integration.leftBoole;
43 import static ffx.numerics.integrate.Integration.leftRectangularMethod;
44 import static ffx.numerics.integrate.Integration.leftSimpsons;
45 import static ffx.numerics.integrate.Integration.leftTrapInput;
46 import static ffx.numerics.integrate.Integration.rightBoole;
47 import static ffx.numerics.integrate.Integration.rightRectangularMethod;
48 import static ffx.numerics.integrate.Integration.rightSimpsons;
49 import static ffx.numerics.integrate.Integration.rightTrapInput;
50 import static org.junit.Assert.assertEquals;
51
52 import ffx.utilities.FFXTest;
53 import org.junit.Before;
54 import org.junit.Test;
55
56 /**
57 * The IntegrationTest is a JUnit test for the Integration program that ensures that the integrals
58 * are calculated correctly. This test is run using known integrals calculated with the equation:
59 *
60 * <p>y = 10 sin(6x) - 7 cos(5x) + 11 sin(8x).
61 *
62 * @author Claire O'Connell
63 */
64 public class IntegrationTest extends FFXTest {
65
66 /** Create array with pointers to doubles that will contain known integrals. */
67 private double[] knownIntegral;
68
69 /** Compares the calculated integrals with the known values. */
70 @Test
71 public void integrationTest() {
72
73 /*
74 * Calculate the integrals using the left hand trapezoidal, Simpson's,
75 * and Boole's methods using data generated with the bounds 1 and 201
76 * with an interval of .1. The second four are the right handed integrals
77 * in the same order.
78 */
79 double[] calculatedIntegral = new double[8];
80
81 calculatedIntegral[0] = leftTrapInput(generateTestData_v1());
82 calculatedIntegral[1] =
83 leftSimpsons(generateTestData_v1()) + halfBinComposite(generateTestData_v1(), 1, "left");
84 calculatedIntegral[2] =
85 leftBoole(generateTestData_v1()) + halfBinComposite(generateTestData_v1(), 2, "left");
86 calculatedIntegral[3] = leftRectangularMethod(generateTestData_v1());
87
88 calculatedIntegral[4] = rightTrapInput(generateTestData_v1());
89 calculatedIntegral[5] =
90 rightSimpsons(generateTestData_v1()) + halfBinComposite(generateTestData_v1(), 1, "right");
91 calculatedIntegral[6] =
92 rightBoole(generateTestData_v1()) + halfBinComposite(generateTestData_v1(), 2, "right");
93 calculatedIntegral[7] = rightRectangularMethod(generateTestData_v1());
94
95 // Set the delta value for the assertEquals comparison.
96 double DELTA = 1e-8;
97
98 // Assert that the known integrals and calculated integrals are the same.
99 for (int i = 0; i < 8; i++) {
100 assertEquals(knownIntegral[i], calculatedIntegral[i], DELTA);
101 }
102 }
103
104 /** Initializes the array before testing. */
105 @Before
106 public void setUp() {
107 // Instantiate the knownIntegral array.
108 knownIntegral = new double[8];
109
110 /*The answers are in the order of the trapezoidal integral first, the
111 Simpson's second, Boole's third, and rectangular method last. The
112 integrals are calculated with the bounds 1 and 201 with an interval of
113 .1. The first four are using left hand integrals and the second four
114 use right hand integrals.
115 */
116 knownIntegral[0] = 2.9684353512887753;
117 knownIntegral[1] = 2.9687126459508564;
118 knownIntegral[2] = 2.968712622691869;
119 knownIntegral[3] = 2.936215172510247;
120
121 knownIntegral[4] = 3.0006927996084642;
122 knownIntegral[5] = 3.000977174918476;
123 knownIntegral[6] = 3.000977149598709;
124 knownIntegral[7] = 2.968898509509485;
125 }
126 }