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    
018    package org.apache.commons.math.ode.nonstiff;
019    
020    import static org.junit.Assert.assertTrue;
021    
022    import java.io.ByteArrayInputStream;
023    import java.io.ByteArrayOutputStream;
024    import java.io.IOException;
025    import java.io.ObjectInputStream;
026    import java.io.ObjectOutputStream;
027    import java.util.Random;
028    
029    import org.apache.commons.math.ode.ContinuousOutputModel;
030    import org.apache.commons.math.ode.DerivativeException;
031    import org.apache.commons.math.ode.IntegratorException;
032    import org.apache.commons.math.ode.TestProblem1;
033    import org.apache.commons.math.ode.TestProblem3;
034    import org.apache.commons.math.ode.sampling.StepHandler;
035    import org.apache.commons.math.ode.sampling.StepInterpolatorTestUtils;
036    import org.junit.Test;
037    
038    public class MidpointStepInterpolatorTest {
039    
040      @Test
041      public void testDerivativesConsistency()
042      throws DerivativeException, IntegratorException {
043        TestProblem3 pb = new TestProblem3();
044        double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.001;
045        MidpointIntegrator integ = new MidpointIntegrator(step);
046        StepInterpolatorTestUtils.checkDerivativesConsistency(integ, pb, 1.0e-10);
047      }
048    
049      @Test
050      public void serialization()
051        throws DerivativeException, IntegratorException,
052               IOException, ClassNotFoundException {
053    
054        TestProblem1 pb = new TestProblem1();
055        double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.001;
056        MidpointIntegrator integ = new MidpointIntegrator(step);
057        integ.addStepHandler(new ContinuousOutputModel());
058        integ.integrate(pb,
059                        pb.getInitialTime(), pb.getInitialState(),
060                        pb.getFinalTime(), new double[pb.getDimension()]);
061    
062        ByteArrayOutputStream bos = new ByteArrayOutputStream();
063        ObjectOutputStream    oos = new ObjectOutputStream(bos);
064        for (StepHandler handler : integ.getStepHandlers()) {
065            oos.writeObject(handler);
066        }
067    
068        assertTrue(bos.size () > 98000);
069        assertTrue(bos.size () < 99000);
070    
071        ByteArrayInputStream  bis = new ByteArrayInputStream(bos.toByteArray());
072        ObjectInputStream     ois = new ObjectInputStream(bis);
073        ContinuousOutputModel cm  = (ContinuousOutputModel) ois.readObject();
074    
075        Random random = new Random(347588535632l);
076        double maxError = 0.0;
077        for (int i = 0; i < 1000; ++i) {
078          double r = random.nextDouble();
079          double time = r * pb.getInitialTime() + (1.0 - r) * pb.getFinalTime();
080          cm.setInterpolatedTime(time);
081          double[] interpolatedY = cm.getInterpolatedState ();
082          double[] theoreticalY  = pb.computeTheoreticalState(time);
083          double dx = interpolatedY[0] - theoreticalY[0];
084          double dy = interpolatedY[1] - theoreticalY[1];
085          double error = dx * dx + dy * dy;
086          if (error > maxError) {
087            maxError = error;
088          }
089        }
090    
091        assertTrue(maxError < 1.0e-6);
092    
093      }
094    
095    }