Source code

Class Numerical

    Assorted, general numerical methods
    
nameargumentsreturns
curve_intersect_interpolatecls, df: pd.DataFrame, row_index :int, x, var1, var2(float, float)
        Fine-tune the intersection point between 2 Pandas dataframe columns,
        using linear interpolation

        :param df:          A Pandas dataframe with at least 3 columns
        :param row_index:   The index of the Pandas dataframe row
                                with the smallest absolute value of difference in concentrations
        :param x:           The name of the dataframe column with the independent variable
        :param var1:        The name of the dataframe column with the data from the 1st curve
        :param var2:        The name of the dataframe column with the data from the 2nd curve
        :return:            The pair (time of intersection, common value)
        
nameargumentsreturns
segment_intersectcls, t, y1, y2(float, float)
        Find the intersection of 2 segments in 2D.
        Their respective endpoints share the same x-coordinates: (t_start, t_end)

        Note: for an alternate method, see line_intersect()

        :param t:   Pair with the joint x-coordinates of the 2 start points,
                        and the joint x-coordinates of the 2 end points
        :param y1:  Pair with the y_coordinates of the endpoints of the 1st segment
        :param y2:  Pair with the y_coordinates of the endpoints of the 2nd segment
                        Note: either segment - but not both - may be horizontal

        :return:    A pair with the (x,y) coord of the intersection;
                        if the segments don't meet their specs (which might result in the lack of an intersection),
                        an Exception is raised
        
nameargumentsreturns
line_intersectcls, p1, p2, q1, q2Union[tuple, None]
        Returns the coordinates of the intersection
        between the line passing thru the points p1 and p2,
        and the line passing thru the points q1 and q2.

        Based on https://stackoverflow.com/a/42727584/5478830

        Note: for an alternate method, see segment_intersect()

        :param p1:  Pair of (x,y) coord of a point on the 1st line
        :param p2:  Pair of (x,y) coord of another point on the 1st line
        :param q1:  Pair of (x,y) coord of a point on the 2nd line
        :param q2:  Pair of (x,y) coord of another point on the 2nd line

        :return:    A pair with the (x,y) coord of the intersection, if it exists;
                        or None if it doesn't exist
        
nameargumentsreturns
deep_flattencls, itemslist
        Completely flatten any lists/tuples of lists or tuples
        into a single list
        EXAMPLES:
            [[1,2,3], [4,5,6], [7], [8,9]] becomes [1, 2, 3, 4, 5, 6, 7, 8, 9]
            (1,2)                       becomes [1,2]
            [(1, 2), (3,4)]             becomes [1, 2, 3, 4]
            5                           becomes [5]
            "hello"                     becomes ["hello"]

        :param items:   A list or tuple possibly containing lists or tuples
        :return:        A flat list
        
nameargumentsreturns
compare_resultscls, res1, res2float
        Use a Euclidean distance metric to compare 2 sets of results - typically from 2 runs
        of different accuracy.
        Each result value may be a number or a list or tuple, possibly containing lists or tuples,
        of numbers.
        However, after the structure is flattened,
        the 2 result data sets must have the same number of points

        :param res1:
        :param res2:
        :return:    The distance between the two sets of value, based on an L2 (Euclidean) metric
        
nameargumentsreturns
compare_vectorscls, v1: np.array, v2: np.array, metric=None, trim_edges=0float
        Return the Euclidean distance between the two given same-sized Numpy arrays
        (TODO: offer option to use alternate metrics)

        :param v1:
        :param v2:
        :param metric:      NOT YET USED: the default L2 norm is always used
        :param trim_edges:  (OPTIONAL) number of elements to ditch at each end,
                                prior to comparing the vectors (default: 0)
        :return:            The distance between the two vectors based on an L2 (Euclidean) metric
        
nameargumentsreturns
compare_statescls, state1: np.array, state2: np.array, verbose=FalseNone
        Print out various assessments of how similar two same-sized Numpy arrays are.
        Typically, those arrays will be system state snapshots - but could be anything.

        :param state1:
        :param state2:
        :param verbose: If True, additional output is shown
        :return:        None
        
nameargumentsreturns
gradient_order4_1dcls, arr, dx=1.0, dtype='float'np.array
        Compute the gradient, from the values in the given array,
        using the 5-point Central Difference, which produces an accuracy of order 4.

        At the boundary, or close to it, different 5-point stencils are used,
        still resulting in an accuracy of order 4.
        For the coefficients, see: https://web.media.mit.edu/~crtaylor/calculator.html

        Returns the same size as the input array.

        For multi-dimensional cases, use gradient_order4()
        For a simpler, but less accurate (order 2) approach, simply use Numpy gradient()

        :param arr:     One-dimensional Numpy array (or list, or tuple) of numbers,
                        with at least 5 elements
        :param dx:      Delta_x (assumed constant)
        :param dtype:   Data type to use for the elements of the returned array

        :return:        A Numpy array with the same size as the one passed in arr
        
nameargumentsreturns
gradient_order4cls, f: np.array, *varargsUnion[np.array, list]
        Compute the gradient, from the values in the given (possibly multidimensional) array,
        using the 5-point Central Difference, which produces an accuracy of order 4.

        At the boundary, and at the points immediately adjacent to the boundary,
        simple 2-point forward or backward differences are used (accuracy order 1.)

        It returns a list of ndarrays (or a single ndarray if there is only 1 dimension).
        Each list element has the same shape as the original array,
        and corresponds to the derivatives of the passed array with respect to each dimension.

        For 1-dimensional cases, can also use gradient_order4_1d(), which produces accuracy order 4 at ALL points.

        (ADAPTED FROM https://gist.github.com/deeplycloudy/1b9fa46d5290314d9be02a5156b48741 , which is
        based on 2nd order version from http://projects.scipy.org/scipy/numpy/browser/trunk/numpy/lib/function_base.py

        :param f:       An N-dimensional array giving samples of a scalar function
        :param varargs: 0, 1, or N scalars giving the sample distances in each direction

        :return:        A list of N numpy arrays,
                        each of the same shape as f giving the derivative of f with respect to each dimension
        
nameargumentsreturns
expand_matrix_boundarycls, mnp.array
        Add a row at the top and at the bottom, and also add a column to the left and to the right,
        repeating the edge values of the matrix
        EXAMPLE:  [[1, 2],
                   [3, 4]]
                 will turn to
                  [[1, 1, 2, 2],
                   [1, 1, 2, 2],
                   [3, 3, 4, 4],
                   [3, 3, 4, 4]]
                 Note how the original matrix is "embedded" in the center of the larger one

        :param m:   A Numpy matrix
        :return:    A Numpy matrix, with 2 extra rows (at top and bottom) and 2 extra columns (at left and right)