示例#1
0
    def test_odeoptions_alloptions(self):
        def mass(t, y, c):
            return [[t, y[0]], [c, t + 1]]

        def events(t, y, c):
            return [[1, 1], [1, 1], [1, 1]]

        y = [1, 2]
        t = 0
        extra = [1]
        try:
            options = {
                'RelTol': 1e-2,
                'AbsTol': [1e-4, 1e-5],
                'NormControl': 'on',
                'NonNegative': [1],
                'Refine': 3,
                'Stats': 'off',
                'InitialStep': 2.3,
                'MaxStep': 4.2e1,
                'Events': events,
                'Mass': mass,
                'MStateDependence': 'weak'
            }
            odeoptions(options, t, y, extra)
        except:
            self.fail("All option correct test failed")
示例#2
0
    def test_odeoptions_abstol(self):
        y = [1, 2]
        t = 0
        extra = []
        try:
            options = {'AbsTol': 1e-2}
            odeoptions(options, t, y, extra)
            options = {'AbsTol': 100}
            odeoptions(options, t, y, extra)
            options = {'AbsTol': 0}
            odeoptions(options, t, y, extra)
            options = {'AbsTol': [0, 1]}
            odeoptions(options, t, y, extra)
            options = {'AbsTol': [0, 1.0]}
            odeoptions(options, t, y, extra)
        except:
            self.fail("AbsTol option correct test failed")

        options = {'AbsTol': -1e-2}
        self.assertRaises(ValueError, odeoptions, options, t, y, extra)
        options = {'AbsTol': '1'}
        self.assertRaises(TypeError, odeoptions, options, t, y, extra)
        options = {'AbsTol': [1, 1.2, 3]}
        self.assertRaises(IndexError, odeoptions, options, t, y, extra)
        options = {'AbsTol': [-1, 1.2]}
        self.assertRaises(ValueError, odeoptions, options, t, y, extra)
        options = {'AbsTol': ['1', 1.2]}
        self.assertRaises(TypeError, odeoptions, options, t, y, extra)
示例#3
0
 def test_odeoptions_nooptions(self):
     options = {}
     y = [1, 2]
     t = 1
     try:
         odeoptions(options, t, y, [])
     except:
         self.fail("No option correct test failed")
示例#4
0
    def test_odeoptions_stats(self):
        y = [1, 2]
        t = 0
        extra = []
        try:
            options = {'Stats': 'on'}
            odeoptions(options, t, y, extra)
            options = {'Stats': 'off'}
            odeoptions(options, t, y, extra)
        except:
            self.fail("Stats option correct test failed")

        options = {'Stats': 2}
        self.assertRaises(ValueError, odeoptions, options, t, y, extra)
        options = {'Stats': 'none'}
        self.assertRaises(ValueError, odeoptions, options, t, y, extra)
示例#5
0
    def test_odeoptions_normcontrol(self):
        y = [1, 2]
        t = 0
        extra = []
        try:
            options = {'NormControl': 'on'}
            odeoptions(options, t, y, extra)
            options = {'NormControl': 'off'}
            odeoptions(options, t, y, extra)
        except:
            self.fail("NormControl option correct test failed")

        options = {'NormControl': 2}
        self.assertRaises(ValueError, odeoptions, options, t, y, extra)
        options = {'NormControl': 'none'}
        self.assertRaises(ValueError, odeoptions, options, t, y, extra)
示例#6
0
    def test_odeoptions_mstatedependence(self):
        y = [1, 2]
        t = 0
        extra = []
        try:
            options = {'MStateDependence': 'weak'}
            odeoptions(options, t, y, extra)
            options = {'MStateDependence': 'none'}
            odeoptions(options, t, y, extra)
        except:
            self.fail("Mass option correct test failed")

        options = {'MStateDependence': 'strong'}
        self.assertRaises(ValueError, odeoptions, options, t, y, extra)
        options = {'MStateDependence': 1.0}
        self.assertRaises(ValueError, odeoptions, options, t, y, extra)
        options = {'MStateDependence': ['weak']}
        self.assertRaises(ValueError, odeoptions, options, t, y, extra)
示例#7
0
    def test_odeoptions_refine(self):
        y = [1, 2]
        t = 0
        extra = []
        try:
            options = {'Refine': 1}
            odeoptions(options, t, y, extra)
            options = {'Refine': 5}
            odeoptions(options, t, y, extra)
        except:
            self.fail("Refine option correct test failed")

        options = {'Refine': 1e-2}
        self.assertRaises(TypeError, odeoptions, options, t, y, extra)
        options = {'Refine': -2}
        self.assertRaises(ValueError, odeoptions, options, t, y, extra)
        options = {'Refine': 0}
        self.assertRaises(ValueError, odeoptions, options, t, y, extra)
示例#8
0
    def test_odeoptions_maxstep(self):
        y = [1, 2]
        t = 0
        extra = []
        try:
            options = {'MaxStep': 1}
            odeoptions(options, t, y, extra)
            options = {'MaxStep': 5e-2}
            odeoptions(options, t, y, extra)
        except:
            self.fail("MaxStep option correct test failed")

        options = {'MaxStep': -1e-2}
        self.assertRaises(ValueError, odeoptions, options, t, y, extra)
        options = {'MaxStep': -1}
        self.assertRaises(ValueError, odeoptions, options, t, y, extra)
        options = {'MaxStep': [1.0]}
        self.assertRaises(TypeError, odeoptions, options, t, y, extra)
        options = {'MaxStep': 'on'}
        self.assertRaises(TypeError, odeoptions, options, t, y, extra)
示例#9
0
    def test_odeoptions_reltol(self):
        y = [1, 2]
        t = 0
        extra = []
        try:
            options = {'RelTol': 1e-2}
            odeoptions(options, t, y, extra)
            options = {'RelTol': 100}
            odeoptions(options, t, y, extra)
            options = {'RelTol': 1e-12}
            odeoptions(options, t, y, extra)
        except:
            self.fail("RelTol option correct test failed")

        options = {'RelTol': -1e-2}
        self.assertRaises(ValueError, odeoptions, options, t, y, extra)
        options = {'RelTol': '1'}
        self.assertRaises(TypeError, odeoptions, options, t, y, extra)
        options = {'RelTol': [1, 1.2]}
        self.assertRaises(TypeError, odeoptions, options, t, y, extra)
示例#10
0
    def test_odeoptions_nonnegative(self):
        y = [1, 2]
        t = 0
        extra = []
        try:
            options = {'NonNegative': []}
            odeoptions(options, t, y, extra)
            options = {'NonNegative': [1]}
            odeoptions(options, t, y, extra)
            options = {'NonNegative': [0, 1]}
            odeoptions(options, t, y, extra)
        except:
            self.fail("NonNegative option correct test failed")

        options = {'NonNegative': [2]}
        self.assertRaises(IndexError, odeoptions, options, t, y, extra)
        options = {'NonNegative': [0, '2']}
        self.assertRaises(TypeError, odeoptions, options, t, y, extra)
        options = {'NonNegative': [1.0]}
        self.assertRaises(TypeError, odeoptions, options, t, y, extra)
        options = {'NonNegative': 'one'}
        self.assertRaises(TypeError, odeoptions, options, t, y, extra)
示例#11
0
    def test_odeoptions_mass(self):
        y = [1, 2]
        t = 0
        extra = []
        try:
            options = {'Mass': [[1, 1], [0, 2]]}
            odeoptions(options, t, y, extra)

            options = {'Mass': np.array([[1, 1], [0, 2]])}
            odeoptions(options, t, y, extra)

            def mass(t):
                return [[t, 0], [0, t + 1]]

            options = {'Mass': mass}
            odeoptions(options, t, y, extra)

            def mass(t, c):
                return [[t, 0], [c, t + 1]]

            options = {'Mass': mass}
            odeoptions(options, t, y, [0])

            def mass(t):
                return np.array([[t, 0], [0, t + 1]])

            options = {'Mass': mass}
            odeoptions(options, t, y, extra)

            def mass(t, c):
                return np.array([[t, 0], [c, t + 1]])

            options = {'Mass': mass}
            odeoptions(options, t, y, [0])

            def mass(t, y):
                return [[t, y[0]], [0, t + 1]]

            options = {'Mass': mass}
            odeoptions(options, t, y, extra)

            def mass(t, y, c):
                return [[t, y[0]], [c, t + 1]]

            options = {'Mass': mass}
            odeoptions(options, t, y, [1])

            def mass(t, y):
                return np.array([[t, y[0]], [0, t + 1]])

            options = {'Mass': mass}
            odeoptions(options, t, y, extra)

            def mass(t, y, c):
                return np.array([[t, y[0]], [c, t + 1]])

            options = {'Mass': mass}
            odeoptions(options, t, y, [1])

        except:
            self.fail("Mass option correct test failed")

        options = {'Mass': 'on'}
        self.assertRaises(TypeError, odeoptions, options, t, y, extra)
        options = {'Mass': [1, 2, 4]}
        self.assertRaises(TypeError, odeoptions, options, t, y, extra)
        options = {'Mass': [1.2, 3]}
        self.assertRaises(TypeError, odeoptions, options, t, y, extra)
        options = {'Mass': [1, 'one']}
        self.assertRaises(TypeError, odeoptions, options, t, y, extra)
        options = {'Mass': [[1, 2], 1]}
        self.assertRaises(TypeError, odeoptions, options, t, y, extra)
        options = {'Mass': [[1, 2], [1, 2, 2]]}
        self.assertRaises(TypeError, odeoptions, options, t, y, extra)
        options = {'Mass': [[1, 2], [1, 'on']]}
        self.assertRaises(ValueError, odeoptions, options, t, y, extra)

        def mass(t, c):
            return [[1, 2], [1, 2]]

        options = {'Mass': mass}
        self.assertRaises(Exception, odeoptions, options, t, y, [1, 2])

        def mass(t, y, c):
            return [[1, 2], [1, 2]]

        options = {'Mass': mass}
        self.assertRaises(Exception, odeoptions, options, t, y, extra)

        def mass(t):
            return 'on'

        options = {'Mass': mass}
        self.assertRaises(TypeError, odeoptions, options, t, y, extra)

        def mass(t):
            return [1, 2, 4]

        options = {'Mass': mass}
        self.assertRaises(TypeError, odeoptions, options, t, y, extra)

        def mass(t):
            return [1.2, 3]

        options = {'Mass': mass}
        self.assertRaises(TypeError, odeoptions, options, t, y, extra)

        def mass(t):
            return [[1, 2], 1]

        options = {'Mass': mass}
        self.assertRaises(TypeError, odeoptions, options, t, y, extra)

        def mass(t):
            return [[1, 2], [1, 2, 2]]

        options = {'Mass': mass}
        self.assertRaises(TypeError, odeoptions, options, t, y, extra)

        def mass(t):
            return [[1, 2], [1, 'on']]

        options = {'Mass': mass}
        self.assertRaises(ValueError, odeoptions, options, t, y, extra)

        def mass(t, y):
            return 'on'

        options = {'Mass': mass}
        self.assertRaises(TypeError, odeoptions, options, t, y, extra)

        def mass(t, y):
            return [1, 2, 4]

        options = {'Mass': mass}
        self.assertRaises(TypeError, odeoptions, options, t, y, extra)

        def mass(t, y):
            return [1.2, 3]

        options = {'Mass': mass}
        self.assertRaises(TypeError, odeoptions, options, t, y, extra)

        def mass(t, y):
            return [[1, 2], 1]

        options = {'Mass': mass}
        self.assertRaises(TypeError, odeoptions, options, t, y, extra)

        def mass(t, y):
            return [[1, 2], [1, 2, 2]]

        options = {'Mass': mass}
        self.assertRaises(TypeError, odeoptions, options, t, y, extra)

        def mass(t, y):
            return [[1, 2], [1, 'on']]

        options = {'Mass': mass}
        self.assertRaises(ValueError, odeoptions, options, t, y, extra)
示例#12
0
    def test_odeoptions_events(self):
        y = [1, 2]
        t = 0

        try:
            extra = []

            def events(t, y):
                return [3.2], [1], [-1]

            options = {'Events': events}
            odeoptions(options, t, y, extra)

            extra = [1, [3, 2]]

            def events(t, y, c, b):
                return [3.2, 2.1], [1, 0], [-1, 1]

            options = {'Events': events}
            odeoptions(options, t, y, extra)

            y = [1, 2]
            extra = [[3, 2]]

            def events(t, y, c):
                return [3.2, c[0]], [1, 0], [-1, 1]

            options = {'Events': events}
            odeoptions(options, t, y, extra)

        except:
            self.fail("Events option correct test failed")

        extra = []
        options = {'Events': [[3.2, 2.1], [1, 0], [-1, 1]]}
        self.assertRaises(TypeError, odeoptions, options, t, y, extra)
        options = {'Events': 'on'}
        self.assertRaises(TypeError, odeoptions, options, t, y, extra)

        def events(t, y):
            return [3.2, 2.1, 3], [1, 0], [-1, 1]

        options = {'Events': events}
        self.assertRaises(ValueError, odeoptions, options, t, y, extra)

        def events(t, y):
            return [3.2, 2.1], [1, 0, 1], [-1, 1]

        options = {'Events': events}
        self.assertRaises(ValueError, odeoptions, options, t, y, extra)

        def events(t, y):
            return [3.2, 2.1], [1, 0], [-1, 1, 0]

        options = {'Events': events}
        self.assertRaises(ValueError, odeoptions, options, t, y, extra)

        def events(t, y):
            return [3.2, '2.1'], [1, 0], [-1, 1]

        options = {'Events': events}
        self.assertRaises(ValueError, odeoptions, options, t, y, extra)

        def events(t, y):
            return [3.2, '2.1'], [1, 0], [-1, 1]

        options = {'Events': events}
        self.assertRaises(ValueError, odeoptions, options, t, y, extra)

        def events(t, y):
            return [[3.2, 2.1], [-1, 0], [0, 1]]

        options = {'Events': events}
        self.assertRaises(ValueError, odeoptions, options, t, y, extra)

        def events(t, y):
            return [[3.2, 2.1], [1, 0], [0, 2]]

        options = {'Events': events}
        self.assertRaises(ValueError, odeoptions, options, t, y, extra)
def odearguments(ode, tspan, y0, options, extras):
    '''Function to verify the inputs of ode45 meet the specifications.
        
    Parameters
    ----------
    ode : callable
        ode function which will be evaluated.
    tspan : array_like, shape(2,) || shape(k,)
        Span over which the function should be evaluated, can be either be a pair [t_0,t_end] or an
        array of specific points.
    y0 : array_like, shape(n,)
        Initial values.
    options : dictionary
        Options, see ode45 sepifications for more information.
    extras : array_like, shape(k,)
        Extra arguments in the function evaluation, if no extra arguments are used then extra is empty. 
        
        
    Returns
    -------
    neq : integer
        Number of equations.
    tspan : array_like, shape(2,) || shape(k,)
        Span over which the function should be evaluated, can be either be a pair [t_0,t_end] or an
        array of specific points.
    ntspan : integer
        Size of tspan.
    nex : 2
        Used in main ode45
    t0 : scalar
        First time to be evaluated.
    tfinal : scalar
        Final time to be evaluated.
    tdir : scalar
        Whether tfinal is greater than t0, 1 if tfinal is greater and -1 otherwise.
    y0 : array_like, shape(n,)
        Initial values.
    f0 : array_like, shape(n,)
        Evaluation of ode for intial values y0.
    args : array_like, shape(k,)
        Extra arguments.
    odeFcn : callable
        ode function.
    options : dictionary.
        options dictionary.
    threshold : scalar || array_like, shape(n,)
        Difference between the absolute tolerance and relative tolerance, if the AbsTol option is a scalar
        then threshold is a scalar, and a array if AbsTol is an array.
    rtol : scalar
        Relative tolerance (RelTol option).
    normcontrol : Bool
        True if NormControl option is 'on', False otherwise.
    normy : scalar
        Norm of the intial values.
    hmax : scalar
        Maximum step size.
    htry : scalar
        Initial step size.
    htspan : scalar
        Difference between t_0 and t_end.
    dataType : numpy dtype
        float64.
    '''

    #Verify y0
    if not isinstance(y0, np.ndarray) and not isinstance(y0, list):
        raise TypeError('odearguments: y0: must be a list or ndarray')
    else:
        if len(y0) == 0:
            raise ValueError(
                'odearguments: y0: must have at least one initial value')
        for i in y0:
            if not isinstance(i, num.Number):
                raise TypeError('odearguments: y0: elements must be numbers')
        neq = len(y0)

    #Verify tspan
    if not isinstance(tspan, np.ndarray) and not isinstance(tspan, list):
        raise TypeError('odearguments: tspan: must be a list or ndarray')
    else:
        if len(tspan) < 2:
            raise ValueError(
                'odearguments: tspan: must have at least two initial values')
        for i in tspan:
            if not isinstance(i, num.Number):
                raise TypeError(
                    'odearguments: tspan: elements must be numbers')

    #Verify ode
    if not callable(ode):
        raise TypeError('odearguments: ode: ode function is not callable')
    else:
        sig = signature(ode)
        if len(sig.parameters) != 2 + len(extras):
            raise TypeError(
                'odearguments: ode: ode function must have the correct number of arguments'
            )
        else:
            result = feval(ode, tspan[0], y0, extras)
            if not isinstance(result, np.ndarray) and not isinstance(
                    result, list):
                raise TypeError(
                    'odearguments: ode: ode function must return a list or ndarray type'
                )
            else:
                if len(result) != len(y0):
                    raise ValueError(
                        'odearguments: ode: ode function must return a list or ndarray type of length equal to y0'
                    )
                for i in result:
                    if not isinstance(i, num.Number):
                        raise TypeError(
                            'odearguments: ode: elements must be numbers')

    #Check options
    odeoptions(options, tspan[0], y0, extras)

    htspan = abs(tspan[1] - tspan[0])
    ntspan = len(tspan)
    t0 = tspan[0]
    nex = 2
    tfinal = tspan[-1]
    args = extras

    #Verify tspan
    if t0 == tfinal:
        raise ValueError(
            'odearguments: tspan: first value and final value must be different'
        )
    tdir = np.sign(tfinal - t0)
    if any(tdir * np.diff(tspan) <= 0):
        raise ValueError('odearguments: tspan: must be monotonic')

    f0 = feval(ode, t0, y0, extras)

    dataType = 'float64'

    #Relative tolerance
    rtol = odeget(options, 'RelTol', 1e-3)
    if rtol < 100 * np.finfo(dataType).eps:
        rtol = 100 * np.finfo(dataType).eps
        warnings.warn('odearguments: rtol: rtol was too small')

    #Absolute tolerance
    atol = odeget(options, 'AbsTol', 1e-6)
    normcontrol = (odeget(options, 'NormControl', 'off') == 'on')
    if normcontrol:
        normy = np.linalg.norm(y0)
    else:
        normy = 0

    if isinstance(atol, list):
        if normcontrol:
            raise ValueError(
                'odearguments: NormControl: when \'on\' AbsTol must be a scalar'
            )
        threshold = [tol / rtol for tol in atol]
    else:
        threshold = atol / rtol

    #Default max step is 1/10 size of the interval
    hmax = min(abs(tfinal - t0),
               abs(odeget(options, 'MaxStep', 0.1 * (tfinal - t0))))
    htry = odeget(options, 'InitialStep', 0)

    odeFcn = ode

    return neq, tspan, ntspan, nex, t0, tfinal, tdir, y0, f0, args, odeFcn, options, threshold, rtol, normcontrol, normy, hmax, htry, htspan, dataType