001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.commons.math.analysis.polynomials;
018    
019    import junit.framework.TestCase;
020    
021    /**
022     * Tests the PolynomialsUtils class.
023     *
024     * @version $Revision: 761213 $ $Date: 2009-04-02 05:05:56 -0400 (Thu, 02 Apr 2009) $
025     */
026    public class PolynomialsUtilsTest extends TestCase {
027    
028        public void testFirstChebyshevPolynomials() {
029    
030            checkPolynomial(PolynomialsUtils.createChebyshevPolynomial(3), "-3.0 x + 4.0 x^3");
031            checkPolynomial(PolynomialsUtils.createChebyshevPolynomial(2), "-1.0 + 2.0 x^2");
032            checkPolynomial(PolynomialsUtils.createChebyshevPolynomial(1), "x");
033            checkPolynomial(PolynomialsUtils.createChebyshevPolynomial(0), "1.0");
034    
035            checkPolynomial(PolynomialsUtils.createChebyshevPolynomial(7), "-7.0 x + 56.0 x^3 - 112.0 x^5 + 64.0 x^7");
036            checkPolynomial(PolynomialsUtils.createChebyshevPolynomial(6), "-1.0 + 18.0 x^2 - 48.0 x^4 + 32.0 x^6");
037            checkPolynomial(PolynomialsUtils.createChebyshevPolynomial(5), "5.0 x - 20.0 x^3 + 16.0 x^5");
038            checkPolynomial(PolynomialsUtils.createChebyshevPolynomial(4), "1.0 - 8.0 x^2 + 8.0 x^4");
039    
040        }
041    
042        public void testChebyshevBounds() {
043            for (int k = 0; k < 12; ++k) {
044                PolynomialFunction Tk = PolynomialsUtils.createChebyshevPolynomial(k);
045                for (double x = -1.0; x <= 1.0; x += 0.02) {
046                    assertTrue(k + " " + Tk.value(x), Math.abs(Tk.value(x)) < (1.0 + 1.0e-12));
047                }
048            }
049        }
050    
051        public void testChebyshevDifferentials() {
052            for (int k = 0; k < 12; ++k) {
053    
054                PolynomialFunction Tk0 = PolynomialsUtils.createChebyshevPolynomial(k);
055                PolynomialFunction Tk1 = Tk0.polynomialDerivative();
056                PolynomialFunction Tk2 = Tk1.polynomialDerivative();
057    
058                PolynomialFunction g0 = new PolynomialFunction(new double[] { k * k });
059                PolynomialFunction g1 = new PolynomialFunction(new double[] { 0, -1});
060                PolynomialFunction g2 = new PolynomialFunction(new double[] { 1, 0, -1 });
061    
062                PolynomialFunction Tk0g0 = Tk0.multiply(g0);
063                PolynomialFunction Tk1g1 = Tk1.multiply(g1);
064                PolynomialFunction Tk2g2 = Tk2.multiply(g2);
065    
066                checkNullPolynomial(Tk0g0.add(Tk1g1.add(Tk2g2)));
067    
068            }
069        }
070    
071        public void testFirstHermitePolynomials() {
072    
073            checkPolynomial(PolynomialsUtils.createHermitePolynomial(3), "-12.0 x + 8.0 x^3");
074            checkPolynomial(PolynomialsUtils.createHermitePolynomial(2), "-2.0 + 4.0 x^2");
075            checkPolynomial(PolynomialsUtils.createHermitePolynomial(1), "2.0 x");
076            checkPolynomial(PolynomialsUtils.createHermitePolynomial(0), "1.0");
077    
078            checkPolynomial(PolynomialsUtils.createHermitePolynomial(7), "-1680.0 x + 3360.0 x^3 - 1344.0 x^5 + 128.0 x^7");
079            checkPolynomial(PolynomialsUtils.createHermitePolynomial(6), "-120.0 + 720.0 x^2 - 480.0 x^4 + 64.0 x^6");
080            checkPolynomial(PolynomialsUtils.createHermitePolynomial(5), "120.0 x - 160.0 x^3 + 32.0 x^5");
081            checkPolynomial(PolynomialsUtils.createHermitePolynomial(4), "12.0 - 48.0 x^2 + 16.0 x^4");
082    
083        }
084    
085        public void testHermiteDifferentials() {
086            for (int k = 0; k < 12; ++k) {
087    
088                PolynomialFunction Hk0 = PolynomialsUtils.createHermitePolynomial(k);
089                PolynomialFunction Hk1 = Hk0.polynomialDerivative();
090                PolynomialFunction Hk2 = Hk1.polynomialDerivative();
091    
092                PolynomialFunction g0 = new PolynomialFunction(new double[] { 2 * k });
093                PolynomialFunction g1 = new PolynomialFunction(new double[] { 0, -2 });
094                PolynomialFunction g2 = new PolynomialFunction(new double[] { 1 });
095    
096                PolynomialFunction Hk0g0 = Hk0.multiply(g0);
097                PolynomialFunction Hk1g1 = Hk1.multiply(g1);
098                PolynomialFunction Hk2g2 = Hk2.multiply(g2);
099    
100                checkNullPolynomial(Hk0g0.add(Hk1g1.add(Hk2g2)));
101    
102            }
103        }
104    
105        public void testFirstLaguerrePolynomials() {
106    
107            checkPolynomial(PolynomialsUtils.createLaguerrePolynomial(3), 6l, "6.0 - 18.0 x + 9.0 x^2 - x^3");
108            checkPolynomial(PolynomialsUtils.createLaguerrePolynomial(2), 2l, "2.0 - 4.0 x + x^2");
109            checkPolynomial(PolynomialsUtils.createLaguerrePolynomial(1), 1l, "1.0 - x");
110            checkPolynomial(PolynomialsUtils.createLaguerrePolynomial(0), 1l, "1.0");
111    
112            checkPolynomial(PolynomialsUtils.createLaguerrePolynomial(7), 5040l,
113                    "5040.0 - 35280.0 x + 52920.0 x^2 - 29400.0 x^3"
114                    + " + 7350.0 x^4 - 882.0 x^5 + 49.0 x^6 - x^7");
115            checkPolynomial(PolynomialsUtils.createLaguerrePolynomial(6),  720l,
116                    "720.0 - 4320.0 x + 5400.0 x^2 - 2400.0 x^3 + 450.0 x^4"
117                    + " - 36.0 x^5 + x^6");
118            checkPolynomial(PolynomialsUtils.createLaguerrePolynomial(5),  120l,
119            "120.0 - 600.0 x + 600.0 x^2 - 200.0 x^3 + 25.0 x^4 - x^5");
120            checkPolynomial(PolynomialsUtils.createLaguerrePolynomial(4),   24l,
121            "24.0 - 96.0 x + 72.0 x^2 - 16.0 x^3 + x^4");
122    
123        }
124    
125        public void testLaguerreDifferentials() {
126            for (int k = 0; k < 12; ++k) {
127    
128                PolynomialFunction Lk0 = PolynomialsUtils.createLaguerrePolynomial(k);
129                PolynomialFunction Lk1 = Lk0.polynomialDerivative();
130                PolynomialFunction Lk2 = Lk1.polynomialDerivative();
131    
132                PolynomialFunction g0 = new PolynomialFunction(new double[] { k });
133                PolynomialFunction g1 = new PolynomialFunction(new double[] { 1, -1 });
134                PolynomialFunction g2 = new PolynomialFunction(new double[] { 0, 1 });
135    
136                PolynomialFunction Lk0g0 = Lk0.multiply(g0);
137                PolynomialFunction Lk1g1 = Lk1.multiply(g1);
138                PolynomialFunction Lk2g2 = Lk2.multiply(g2);
139    
140                checkNullPolynomial(Lk0g0.add(Lk1g1.add(Lk2g2)));
141    
142            }
143        }
144    
145        public void testFirstLegendrePolynomials() {
146    
147            checkPolynomial(PolynomialsUtils.createLegendrePolynomial(3),  2l, "-3.0 x + 5.0 x^3");
148            checkPolynomial(PolynomialsUtils.createLegendrePolynomial(2),  2l, "-1.0 + 3.0 x^2");
149            checkPolynomial(PolynomialsUtils.createLegendrePolynomial(1),  1l, "x");
150            checkPolynomial(PolynomialsUtils.createLegendrePolynomial(0),  1l, "1.0");
151    
152            checkPolynomial(PolynomialsUtils.createLegendrePolynomial(7), 16l, "-35.0 x + 315.0 x^3 - 693.0 x^5 + 429.0 x^7");
153            checkPolynomial(PolynomialsUtils.createLegendrePolynomial(6), 16l, "-5.0 + 105.0 x^2 - 315.0 x^4 + 231.0 x^6");
154            checkPolynomial(PolynomialsUtils.createLegendrePolynomial(5),  8l, "15.0 x - 70.0 x^3 + 63.0 x^5");
155            checkPolynomial(PolynomialsUtils.createLegendrePolynomial(4),  8l, "3.0 - 30.0 x^2 + 35.0 x^4");
156    
157        }
158    
159        public void testLegendreDifferentials() {
160            for (int k = 0; k < 12; ++k) {
161    
162                PolynomialFunction Pk0 = PolynomialsUtils.createLegendrePolynomial(k);
163                PolynomialFunction Pk1 = Pk0.polynomialDerivative();
164                PolynomialFunction Pk2 = Pk1.polynomialDerivative();
165    
166                PolynomialFunction g0 = new PolynomialFunction(new double[] { k * (k + 1) });
167                PolynomialFunction g1 = new PolynomialFunction(new double[] { 0, -2 });
168                PolynomialFunction g2 = new PolynomialFunction(new double[] { 1, 0, -1 });
169    
170                PolynomialFunction Pk0g0 = Pk0.multiply(g0);
171                PolynomialFunction Pk1g1 = Pk1.multiply(g1);
172                PolynomialFunction Pk2g2 = Pk2.multiply(g2);
173    
174                checkNullPolynomial(Pk0g0.add(Pk1g1.add(Pk2g2)));
175    
176            }
177        }
178    
179        public void testHighDegreeLegendre() {
180            PolynomialsUtils.createLegendrePolynomial(40);
181            double[] l40 = PolynomialsUtils.createLegendrePolynomial(40).getCoefficients();
182            double denominator = 274877906944.0;
183            double[] numerators = new double[] {
184                              +34461632205.0,            -28258538408100.0,          +3847870979902950.0,        -207785032914759300.0,
185                      +5929294332103310025.0,     -103301483474866556880.0,    +1197358103913226000200.0,    -9763073770369381232400.0,
186                  +58171647881784229843050.0,  -260061484647976556945400.0,  +888315281771246239250340.0, -2345767627188139419665400.0,
187                +4819022625419112503443050.0, -7710436200670580005508880.0, +9566652323054238154983240.0, -9104813935044723209570256.0,
188                +6516550296251767619752905.0, -3391858621221953912598660.0, +1211378079007840683070950.0,  -265365894974690562152100.0,
189                  +26876802183334044115405.0
190            };
191            for (int i = 0; i < l40.length; ++i) {
192                if (i % 2 == 0) {
193                    double ci = numerators[i / 2] / denominator;
194                    assertEquals(ci, l40[i], Math.abs(ci) * 1.0e-15);
195                } else {
196                    assertEquals(0.0, l40[i], 0.0);
197                }
198            }
199        }
200    
201        private void checkPolynomial(PolynomialFunction p, long denominator, String reference) {
202            PolynomialFunction q = new PolynomialFunction(new double[] { denominator});
203            assertEquals(reference, p.multiply(q).toString());
204        }
205    
206        private void checkPolynomial(PolynomialFunction p, String reference) {
207            assertEquals(reference, p.toString());
208        }
209    
210        private void checkNullPolynomial(PolynomialFunction p) {
211            for (double coefficient : p.getCoefficients()) {
212                assertEquals(0.0, coefficient, 1.0e-13);
213            }
214        }
215    
216    }