Sisällysluettelo

Lyhyt dokumentaatio ohjelmasta, joka ratkaisee numeerisesti kahden pisteen reuna-arvotehtävän.

Tämä dokumentti jupyter-notebookina

Ongelma, joka tuottaa tässä ratkaistavan kahden-pisteen reuna-arvotehtävän

Ratkaisen reuna-arvotehtävän scikits.bvp_solver-algoritmilla. Minun koneeseeni se installoitui paikkaan, josta python ei sitä löytänyt, joten tein allaolevan tempun. (Installoin komennolla pip3.6 install scikits.bvp_solver)

Numeerisen algoritmin konvergointi eli se, löytääkö algoritmi ratkaisun, riippuu alkuarvauksesta ja tehtävään liittyvistä parametreista. 'Käsityönä' koodaamani alkuarvaus antoi ratkaisun vain sellaisilla optimikustannuksen painokertoimilla, jotka eivät mielestäni olleet mielenkiintoisia. Niinpä tein funktion guess, joka muuttaa optimoinnin tuloksen uudeksi alkuarvaukseksi bvp_solverin toivomaan muotoon seuraavaa optimointia varten. Uusi alkuarvaus 'kestää' mielenkiintoisempia painokertoimia.

Alempana määritelty funktio ratkaisu hakee optimiohjauksen kutsumalla funktiota scikits.bvp_solver.solve

def solve(bvp_problem,
          solution_guess,
          initial_mesh = None,
          parameter_guess = None,
          max_subintervals = 300,
          singular_term = None,
          tolerance = 1.0e-6,
          method = 4,
          trace = 0,
          error_on_fail = True):
    """Attempts to solve the supplied boundary value problem starting from the user supplied guess for the solution using BVP_SOLVER.

    Parameters
    ----------
    bvp_problem : :class:`ProblemDefinition`
        Defines the boundary value problem to be solved.
    solution_guess : :class:`Solution`, constant, array of values or function
        A guess for the solution.
    initial_mesh : castable to floating point ndarray
        Points on the x-axis to use for the supplied solution guess, default is 10 evenly spaced points. Must not be supplied if solution_guess is a :class:`Solution` object.
    parameter_guess : castable to floating point ndarray, shape (num_parameters)
        Guesses for the unknown parameters. Must not be supplied if solution_guess is a :class:`Solution` object.
    max_subintervals : int
        Maximum number of points on the mesh before an error is returned.
    singular_term : castable to floating point ndarray, shape(num_ODE, num_ODE)
        Matrix that defines the singular term for the problem if one exist.
    tolerance : positive float
        Tolerance for size of defect of approximate solution.
    method : {2, 4, 6}
        Order of Runge-Kutta to use.
    trace : {0, 1, 2}
        Indicates verbosity of output. 0 for no output, 1 for some output, 2 for full output.
    error_on_fail : logical
        Indicates whether an exception should be raised if solving fails.

    Returns
    -------
    sol : :class:`Solution`
        Approximate problem solution.

    Raises
    ------
    ValueError
        If bvp_problem failed validation in some way.
    ValueError
        If solving fails.
    """

Pythonilla kuvaajia voi piirrellä interaktiivisessa moodissa, jolloin grafiikkaohjelmisto jää odottamaan käyttäjältä lisäkomentoja. Minusta ohjelma "panttasi" joidenkin kuvaajien piirtämistä, joten käänsin interaktiivisen moodin pois päältä

plotdim on aikapisteiden lukumäärä, joissa ratkaisu esitetään. Tämä on turhan paljon, mutta videopeli päivittää tilansa 48 kertaa sekunnissa, joten näin saan kätevästi automaattiohjauksen ohjausvoimat suoraan kullekin aikahetkellä.

'Käsinkoodaamani' varsinainen alkuarvaus

class ProblemDefinition:
    """Defines a boundary value problem.
    """
    def __init__(self,
                 num_ODE,
                 num_parameters,
                 num_left_boundary_conditions,
                 boundary_points,
                 function,
                 boundary_conditions,
                 function_derivative = None,
                 boundary_conditions_derivative = None):
        """
        Parameters
        ----------
        num_ODE : int
            Number of first order ordinary differential equations in the problem.
        num_parameters : int
            Number of unknown parameters in the problem.
        num_left_boundary_conditions : int
            Number of boundary conditions enforced on the left boundary.
        boundary_points : arraylike, shape(2)
            Array that defines the two boundary points on the x axis.
        function : function (see definition below)
            A function which calculates the value of the ODE equations.

                function (X, Y[, P]):

                    Parameters:
                        X : float
                            scalar value of x at which to evaluate the ODEs

                        Y : ndarray, shape(num_ODE)
                            current value of all variables

                        P : ndarray, shape(num_parameters)
                            value of all unknown parameters (only included if num_parameters > 0)
                    Returns:
                        ODE : ndarray, shape(num_ODE)
                            array of all ODEs

        boundary_conditions : function (see definition below)
            A function which calculates the difference between the boundary conditions and the actual variables currently calculated.

                boundary_conditions(YA, YB[, P]):

                    Parameters:
                        YA : ndarray, shape(num_ODE)
                            value of all variables at the left boundary

                        YB : ndarray, shape(num_ODE)
                            value of all variables at the right boundary

                        P : ndarray, shape(num_parameters)
                            value of all unknown parameters (only used if num_parameters > 0)

                    Returns:
                        BCA : ndarray, shape(num_left_boundary_conditions)
                            difference between the boundary condition and variables at the left boundary

                        BCB : ndarray, shape(num_ODE + num_parameters - num_left_boundary_conditions)
                            array of the difference between the boundary condition and variables at the right boundary

        function_derivative : optional function (see definition below)
            A function which returns the partial derivatives of the function argument.

                function (X, Y[, P]):

                    Parameters:
                        X : float
                            scalar value of x at which to evaluate the ODEs

                        Y : ndarray, shape(num_ODE)
                            current value of all variables

                        P : ndarray, shape(num_parameters)
                            value of all unknown parameters (only included if num_parameters > 0)
                    Returns:
                        dODE : ndarray, shape(num_ODE, num_ODE)
                            array of partial derivative of all ODEs with respect to all variables; index of ODEs is first, index of variables is second

                        dOdP : ndarray, shape(num_ODE, num_parameters)
                            array of partial derivative of all ODEs with respect to all unknown parameters; index of ODEs is first, index of parameters is second must not be returned if the problem does not include unknown parameters


        boundary_conditions_drivative : optional function (see definition below)
            A function which returns the partial derivatives of the boundary_conditions argument.
                boundary_conditions(YA, YB[, P]):

                    Parameters:
                        YA : ndarray, shape(num_ODE)
                            value of all variables at the left boundary

                        YB : ndarray, shape(num_ODE)
                            value of all variables at the right boundary

                        P : ndarray, shape(num_parameters)
                            value of all unknown parameters (only used if num_parameters > 0)

                    Returns:
                        dBCA : ndarray, shape(num_left_boundary_conditions, num_ODE)
                            partial derivatives of the difference between the left boundary condition and the actual variables at the left boundary; boundary condition index is first and variable index is second

                        dBCB : ndarray, shape(num_ODE + num_parameters - num_left_boundary_conditions, num_ODE)
                            partial derivatives of the difference between the right boundary condition and the actual variables at the right boundary; boundary condition index is first and variable index is second

                        dBPA : ndarray, shape(num_left_boundary_conditions, num_parameters)
                            partial derivatives of the difference between the left boundary condition and the unknown parameters; boundary condition index is first and parameter index is second

                        dBPB : ndarray, shape(num_ODE + num_parameters - num_left_boundary_conditions, num_parameters)
                            partial derivatives of the difference between the right boundary condition and the unknown parameters; boundary condition index is first and parameter index is second
"""