def test_rounded_list(self):
     rounded_list_main = rounded_list(
         [3.12718492, 2.17729, 54.21, 8.9999222222, 3.9274826, 115.28191],
         6)
     self.assertEqual(
         rounded_list_main,
         [3.127185, 2.17729, 54.21, 8.999922, 3.927483, 115.28191])
def sinusoidal_roots_derivative_initial_value(first_constant, second_constant, third_constant, fourth_constant, initial_value, precision = 4):
    # Handle input errors
    five_scalars(first_constant, second_constant, third_constant, fourth_constant, initial_value)
    positive_integer(precision)

    # Create intermediary list and list to return
    roots = []
    result = []

    # Identify key ratio
    ratio = initial_value / (first_constant * second_constant)

    # Handle no roots
    if ratio > 1 or ratio < -1:
        result.append(None)
    
    # Handle multiple roots
    else:
        # Handle case in which initial value is zero
        if ratio == 0:
            roots = sinusoidal_roots_first_derivative(first_constant, second_constant, third_constant, fourth_constant, precision)
        
        # Handle general case
        else:
            radians = acos(ratio)
            periodic_radians = radians / second_constant
            periodic_unit = 2 * pi / second_constant
            initial = third_constant + periodic_radians
            roots = generate_elements(initial, periodic_unit, precision)

            # Handle roots that bounce on the x-axis
            if ratio == 1 or ratio == -1:
                pass

            # Handle roots that cross the x-axis
            else:
                alternative_initial = third_constant + periodic_unit - periodic_radians
                generated_elements = generate_elements(alternative_initial, periodic_unit, precision)
                roots.extend(generated_elements)
        
        # Separate numerical roots, string roots, and None results
        separated_roots = separate_elements(roots)
        numerical_roots = separated_roots['numerical']
        other_roots = separated_roots['other']
        
        # Sort numerical roots
        sorted_roots = sorted_list(numerical_roots)

        # Round numerical roots
        rounded_roots = rounded_list(sorted_roots, precision)
        
        # Sort other_roots
        sorted_other_roots = sorted_strings(other_roots)

        # Combine numerical and non-numerical roots
        result.extend(rounded_roots + sorted_other_roots)
    
    # Return result
    return result
示例#3
0
def shifted_points_within_range(points, minimum, maximum, precision = 4):
    # Handle input errors
    allow_vector_matrix(points, 'first')
    compare_scalars(minimum, maximum, 'second', 'third')
    positive_integer(precision)

    # Grab general points
    general_points = []
    for point in points:
        # Handle coordinate pairs
        if isinstance(point, list):
            if isinstance(point[0], str):
                general_points.append(point[0])
        
        # Handle single coordinates
        else:
            if isinstance(point, str):
                general_points.append(point)
    
    # Generate options for inputs
    optional_points = []
    for point in general_points:
        # Grab initial value and periodic unit
        initial_value_index = point.find(' + ')
        initial_value = float(point[:initial_value_index])
        periodic_unit_index = initial_value_index + 3
        periodic_unit = float(point[periodic_unit_index:-1])
        
        # Increase or decrease initial value to fit into range
        alternative_initial_value = shift_into_range(initial_value, periodic_unit, minimum, maximum)
        
        # Generate additional values within range
        generated_elements = generate_elements(alternative_initial_value, periodic_unit, precision)
        optional_points += generated_elements
    
    # Separate numerical inputs from string inputs
    separated_points = separate_elements(optional_points)
    numerical_points = separated_points['numerical']
    other_points = separated_points['other']

    # Sort numerical inputs
    sorted_points = sorted_list(numerical_points)

    # Reduce numerical inputs to within a given range
    selected_points = [x for x in sorted_points if x >= minimum and x <= maximum]
    
    # Round numerical inputs
    rounded_points = rounded_list(selected_points, precision)
    
    # Sort string inputs
    sorted_other_points = sorted_strings(other_points)
    
    # Combine numerical and string inputs
    result = rounded_points + sorted_other_points
    return result
示例#4
0
def sinusoidal_derivatives(first_constant,
                           second_constant,
                           third_constant,
                           fourth_constant,
                           precision=4):
    """
    Calculates the first and second derivatives of a sinusoidal function

    Parameters
    ----------
    first_constant : int or float
        Vertical stretch factor of the original sine function; if zero, it will be converted to a small, non-zero decimal value (e.g., 0.0001)
    second_constant : int or float
        Horizontal stretch factor of the original sine function; if zero, it will be converted to a small, non-zero decimal value (e.g., 0.0001)
    third_constant : int or float
        Horizontal shift of the original sine function; if zero, it will be converted to a small, non-zero decimal value (e.g., 0.0001)
    fourth_constant : int or float
        Vertical shift of the original sine function; if zero, it will be converted to a small, non-zero decimal value (e.g., 0.0001)
    precision : int, default=4
        Maximum number of digits that can appear after the decimal place of the resultant roots

    Raises
    ------
    TypeError
        First four arguments must be integers or floats
    ValueError
        Last argument must be a positive integer

    Returns
    -------
    derivatives['first']['constants'] : list of float
        Coefficients of the resultant first derivative
    derivatives['first']['evaluation'] : func
        Function for evaluating the resultant first derivative at any float or integer argument
    derivatives['second']['constants'] : list of float
        Coefficients of the resultant second derivative
    derivatives['second']['evaluation'] : func
        Function for evaluating the resultant second derivative at any float or integer argument

    See Also
    --------
    :func:`~regressions.analyses.equations.sinusoidal.sinusoidal_equation`, :func:`~regressions.analyses.integrals.sinusoidal.sinusoidal_integral`, :func:`~regressions.analyses.roots.sinusoidal.sinusoidal_roots`, :func:`~regressions.models.sinusoidal.sinusoidal_model`

    Notes
    -----
    - Standard form of a sinusoidal function: :math:`f(x) = a\\cdot{\\sin(b\\cdot(x - c))} + d`
    - First derivative of a sinusoidal function: :math:`f'(x) = ab\\cdot{\\cos(b\\cdot(x - c))}`
    - Second derivative of a sinusoidal function: :math:`f''(x) = -ab^2\\cdot{\\sin(b\\cdot(x - c))}`
    - |differentiation_formulas|
    - |chain_rule|
    - |trigonometric|

    Examples
    --------
    Import `sinusoidal_derivatives` function from `regressions` library
        >>> from regressions.analyses.derivatives.sinusoidal import sinusoidal_derivatives
    Generate the derivatives of a sinusoidal function with coefficients 2, 3, 5, and 7, then display the coefficients of its first and second derivatives
        >>> derivatives_constants = sinusoidal_derivatives(2, 3, 5, 7)
        >>> print(derivatives_constants['first']['constants'])
        [6.0, 3.0, 5.0]
        >>> print(derivatives_constants['second']['constants'])
        [-18.0, 3.0, 5.0]
    Generate the derivatives of a sinusoidal function with coefficients 7, -5, -3, and 2, then evaluate its first and second derivatives at 10
        >>> derivatives_evaluation = sinusoidal_derivatives(7, -5, -3, 2)
        >>> print(derivatives_evaluation['first']['evaluation'](10))
        19.6859
        >>> print(derivatives_evaluation['second']['evaluation'](10))
        144.695
    Generate the derivatives of a sinusoidal function with all inputs set to 0, then display the coefficients of its first and second derivatives
        >>> derivatives_zeroes = sinusoidal_derivatives(0, 0, 0, 0)
        >>> print(derivatives_zeroes['first']['constants'])
        [0.0001, 0.0001, 0.0001]
        >>> print(derivatives_zeroes['second']['constants'])
        [-0.0001, 0.0001, 0.0001]
    """
    # Handle input errors
    four_scalars(first_constant, second_constant, third_constant,
                 fourth_constant)
    positive_integer(precision)
    coefficients = no_zeroes(
        [first_constant, second_constant, third_constant, fourth_constant],
        precision)

    # Create first derivative
    first_coefficients = [
        coefficients[0] * coefficients[1], coefficients[1], coefficients[2]
    ]
    first_constants = rounded_list(first_coefficients, precision)

    def first_derivative(variable):
        evaluation = first_constants[0] * cos(first_constants[1] *
                                              (variable - first_constants[2]))
        rounded_evaluation = rounded_value(evaluation, precision)
        return rounded_evaluation

    first_dictionary = {
        'constants': first_constants,
        'evaluation': first_derivative
    }

    # Create second derivative
    second_coefficients = [
        -1 * first_constants[0] * first_constants[1], first_constants[1],
        first_constants[2]
    ]
    second_constants = rounded_list(second_coefficients, precision)

    def second_derivative(variable):
        evaluation = second_constants[0] * sin(
            second_constants[1] * (variable - second_constants[2]))
        rounded_evaluation = rounded_value(evaluation, precision)
        return rounded_evaluation

    second_dictionary = {
        'constants': second_constants,
        'evaluation': second_derivative
    }

    # Package both derivatives in single dictionary
    results = {'first': first_dictionary, 'second': second_dictionary}
    return results
示例#5
0
def quadratic_roots(first_constant,
                    second_constant,
                    third_constant,
                    precision=4):
    """
    Calculates the roots of a quadratic function

    Parameters
    ----------
    first_constant : int or float
        Coefficient of the quadratic term of the original quadratic function; if zero, it will be converted to a small, non-zero decimal value (e.g., 0.0001)
    second_constant : int or float
        Coefficient of the linear term of the original quadratic function; if zero, it will be converted to a small, non-zero decimal value (e.g., 0.0001)
    third_constant : int or float
        Coefficient of the constant term of the original quadratic function; if zero, it will be converted to a small, non-zero decimal value (e.g., 0.0001)
    precision : int, default=4
        Maximum number of digits that can appear after the decimal place of the resultant roots

    Raises
    ------
    TypeError
        First three arguments must be integers or floats
    ValueError
        Last argument must be a positive integer

    Returns
    -------
    roots : list of float
        List of the x-coordinates of all of the x-intercepts of the original function; if the function never crosses the x-axis, then it will return a list of `None`

    See Also
    --------
    :func:`~regressions.analyses.equations.quadratic.quadratic_equation`, :func:`~regressions.analyses.derivatives.quadratic.quadratic_derivatives`, :func:`~regressions.analyses.integrals.quadratic.quadratic_integral`, :func:`~regressions.models.quadratic.quadratic_model`

    Notes
    -----
    - Standard form of a quadratic function: :math:`f(x) = a\\cdot{x^2} + b\\cdot{x} + c`
    - Quadratic formula: :math:`x = \\frac{-b \\pm \\sqrt{b^2 - 4ac}}{2a}`
    - |quadratic_formula|

    Examples
    --------
    Import `quadratic_roots` function from `regressions` library
        >>> from regressions.analyses.roots.quadratic import quadratic_roots
    Calculate the roots of a quadratic function with coefficients 2, 7, and 5
        >>> roots_first = quadratic_roots(2, 7, 5)
        >>> print(roots_first)
        [-2.5, -1.0]
    Calculate the roots of a quadratic function with coefficients 2, -5, and 3
        >>> roots_second = quadratic_roots(2, -5, 3)
        >>> print(roots_second)
        [1.0, 1.5]
    Calculate the roots of a quadratic function with all inputs set to 0
        >>> roots_zeroes = quadratic_roots(0, 0, 0)
        >>> print(roots_zeroes)
        [None]
    """
    # Handle input errors
    three_scalars(first_constant, second_constant, third_constant)
    positive_integer(precision)
    coefficients = no_zeroes([first_constant, second_constant, third_constant],
                             precision)

    # Create intermediary list and list to return
    roots = []
    result = []

    # Create intermediary variable
    discriminant = coefficients[1]**2 - 4 * coefficients[0] * coefficients[2]

    # Create roots
    first_root = (-1 * coefficients[1] +
                  discriminant**(1 / 2)) / (2 * coefficients[0])
    second_root = (-1 * coefficients[1] -
                   discriminant**(1 / 2)) / (2 * coefficients[0])

    # Eliminate duplicate roots
    if first_root == second_root:
        roots.append(first_root)

    # Eliminate complex roots
    else:
        if not isinstance(first_root, complex):
            roots.append(first_root)
        if not isinstance(second_root, complex):
            roots.append(second_root)

    # Handle no roots
    if not roots:
        roots.append(None)

    # Sort roots
    sorted_roots = sorted_list(roots)

    # Round roots
    rounded_roots = rounded_list(sorted_roots, precision)

    # Return result
    result.extend(rounded_roots)
    return result
def sinusoidal_integral(first_constant,
                        second_constant,
                        third_constant,
                        fourth_constant,
                        precision=4):
    """
    Generates the integral of a sinusoidal function

    Parameters
    ----------
    first_constant : int or float
        Vertical stretch factor of the original sine function; if zero, it will be converted to a small, non-zero decimal value (e.g., 0.0001)
    second_constant : int or float
        Horizontal stretch factor of the original sine function; if zero, it will be converted to a small, non-zero decimal value (e.g., 0.0001)
    third_constant : int or float
        Horizontal shift of the original sine function; if zero, it will be converted to a small, non-zero decimal value (e.g., 0.0001)
    fourth_constant : int or float
        Vertical shift of the original sine function; if zero, it will be converted to a small, non-zero decimal value (e.g., 0.0001)
    precision : int, default=4
        Maximum number of digits that can appear after the decimal place of the resultant roots

    Raises
    ------
    TypeError
        First four arguments must be integers or floats
    ValueError
        Last argument must be a positive integer

    Returns
    -------
    integral['constants'] : list of float
        Coefficients of the resultant integral
    integral['evaluation'] : func
        Function for evaluating the resultant integral at any float or integer argument

    See Also
    --------
    :func:`~regressions.analyses.equations.sinusoidal.sinusoidal_equation`, :func:`~regressions.analyses.derivatives.sinusoidal.sinusoidal_derivatives`, :func:`~regressions.analyses.roots.sinusoidal.sinusoidal_roots`, :func:`~regressions.models.sinusoidal.sinusoidal_model`

    Notes
    -----
    - Standard form of a sinusoidal function: :math:`f(x) = a\\cdot{\\sin(b\\cdot(x - c))} + d`
    - Integral of a sinusoidal function: :math:`F(x) = -\\frac{a}{b}\\cdot{\\cos(b\\cdot(x - c))} + d\\cdot{x}`
    - |indefinite_integral|
    - |integration_formulas|
    - |substitution_rule|

    Examples
    --------
    Import `sinusoidal_integral` function from `regressions` library
        >>> from regressions.analyses.integrals.sinusoidal import sinusoidal_integral
    Generate the integral of a sinusoidal function with coefficients 2, 3, 5, and 7, then display its coefficients
        >>> integral_constants = sinusoidal_integral(2, 3, 5, 7)
        >>> print(integral_constants['constants'])
        [-0.6667, 3.0, 5.0, 7.0]
    Generate the integral of a sinusoidal function with coefficients 7, -5, -3, and 2, then evaluate its integral at 10
        >>> integral_evaluation = sinusoidal_integral(7, -5, -3, 2)
        >>> print(integral_evaluation['evaluation'](10))
        19.2126
    Generate the integral of a sinusoidal function with all inputs set to 0, then display its coefficients
        >>> integral_zeroes = sinusoidal_integral(0, 0, 0, 0)
        >>> print(integral_zeroes['constants'])
        [-1.0, 0.0001, 0.0001, 0.0001]
    """
    # Handle input errors
    four_scalars(first_constant, second_constant, third_constant,
                 fourth_constant)
    positive_integer(precision)
    coefficients = no_zeroes(
        [first_constant, second_constant, third_constant, fourth_constant],
        precision)

    # Create constants
    integral_coefficients = [
        -1 * coefficients[0] / coefficients[1], coefficients[1],
        coefficients[2], coefficients[3]
    ]
    constants = rounded_list(integral_coefficients, precision)

    # Create evaluation
    def sinusoidal_evaluation(variable):
        evaluation = constants[0] * cos(
            constants[1] * (variable - constants[2])) + constants[3] * variable
        rounded_evaluation = rounded_value(evaluation, precision)
        return rounded_evaluation

    # Package constants and evaluation in single dictionary
    results = {'constants': constants, 'evaluation': sinusoidal_evaluation}
    return results
示例#7
0
def exponential_integral(first_constant, second_constant, precision = 4):
    """
    Generates the integral of an exponential function

    Parameters
    ----------
    first_constant : int or float
        Constant multiple of the original exponential function; if zero, it will be converted to a small, non-zero decimal value (e.g., 0.0001)
    second_constant : int or float
        Base rate of variable of the original exponential function; if zero, it will be converted to a small, non-zero decimal value (e.g., 0.0001); if one, it will be converted to a small, near-one decimal value (e.g., 1.0001)
    precision : int, default=4
        Maximum number of digits that can appear after the decimal place of the resultant roots

    Raises
    ------
    TypeError
        First two arguments must be integers or floats
    ValueError
        Last argument must be a positive integer

    Returns
    -------
    integral['constants'] : list of float
        Coefficients of the resultant integral
    integral['evaluation'] : func
        Function for evaluating the resultant integral at any float or integer argument

    See Also
    --------
    :func:`~regressions.analyses.equations.exponential.exponential_equation`, :func:`~regressions.analyses.derivatives.exponential.exponential_derivatives`, :func:`~regressions.analyses.roots.exponential.exponential_roots`, :func:`~regressions.models.exponential.exponential_model`

    Notes
    -----
    - Standard form of an exponential function: :math:`f(x) = a\\cdot{b^x}`
    - Integral of an exponential function: :math:`F(x) = \\frac{a}{\\ln{b}}\\cdot{b^x}`
    - |indefinite_integral|
    - |integration_formulas|

    Examples
    --------
    Import `exponential_integral` function from `regressions` library
        >>> from regressions.analyses.integrals.exponential import exponential_integral
    Generate the integral of an exponential function with coefficients 2 and 3, then display its coefficients
        >>> integral_constants = exponential_integral(2, 3)
        >>> print(integral_constants['constants'])
        [1.8205, 3.0]
    Generate the integral of an exponential function with coefficients -2 and 3, then evaluate its integral at 10
        >>> integral_evaluation = exponential_integral(-2, 3)
        >>> print(integral_evaluation['evaluation'](10))
        -107498.7045
    Generate the integral of an exponential function with all inputs set to 0, then display its coefficients
        >>> integral_zeroes = exponential_integral(0, 0)
        >>> print(integral_zeroes['constants'])
        [-0.0001, 0.0001]
    """
    # Handle input errors
    two_scalars(first_constant, second_constant)
    positive_integer(precision)
    coefficients = no_zeroes([first_constant, second_constant], precision)

    # Circumvent division by zero
    if coefficients[1] == 1:
        coefficients[1] = 1 + 10**(-precision)
    
    # Create constants
    integral_coefficients = [coefficients[0] / log(abs(coefficients[1])), coefficients[1]]
    constants = rounded_list(integral_coefficients, precision)

    # Create evaluation
    def exponential_evaluation(variable):
        evaluation = constants[0] * constants[1]**variable
        rounded_evaluation = rounded_value(evaluation, precision)
        return rounded_evaluation
    
    # Package constants and evaluation in single dictionary
    results = {
        'constants': constants,
        'evaluation': exponential_evaluation
    }
    return results
示例#8
0
def logistic_integral(first_constant,
                      second_constant,
                      third_constant,
                      precision=4):
    """
    Generates the integral of a logistic function

    Parameters
    ----------
    first_constant : int or float
        Carrying capacity of the original logistic function; if zero, it will be converted to a small, non-zero decimal value (e.g., 0.0001)
    second_constant : int or float
        Growth rate of the original logistic function; if zero, it will be converted to a small, non-zero decimal value (e.g., 0.0001)
    third_constant : int or float
        Value of the sigmoid's midpoint of the original logistic function; if zero, it will be converted to a small, non-zero decimal value (e.g., 0.0001)
    precision : int, default=4
        Maximum number of digits that can appear after the decimal place of the resultant roots

    Raises
    ------
    TypeError
        First three arguments must be integers or floats
    ValueError
        Last argument must be a positive integer

    Returns
    -------
    integral['constants'] : list of float
        Coefficients of the resultant integral
    integral['evaluation'] : func
        Function for evaluating the resultant integral at any float or integer argument

    See Also
    --------
    :func:`~regressions.analyses.equations.logistic.logistic_equation`, :func:`~regressions.analyses.derivatives.logistic.logistic_derivatives`, :func:`~regressions.analyses.roots.logistic.logistic_roots`, :func:`~regressions.models.logistic.logistic_model`

    Notes
    -----
    - Standard form of a logistic function: :math:`f(x) = \\frac{a}{1 + \\text{e}^{-b\\cdot(x - c)}}`
    - Integral of a logistic function: :math:`F(x) = \\frac{a}{b}\\cdot{\\ln|\\text{e}^{b\\cdot(x - c)} + 1|}`
    - |indefinite_integral|
    - |integration_formulas|
    - |substitution_rule|

    Examples
    --------
    Import `logistic_integral` function from `regressions` library
        >>> from regressions.analyses.integrals.logistic import logistic_integral
    Generate the integral of a logistic function with coefficients 2, 3, and 5, then display its coefficients
        >>> integral_constants = logistic_integral(2, 3, 5)
        >>> print(integral_constants['constants'])
        [0.6667, 3.0, 5.0]
    Generate the integral of a logistic function with coefficients 100, 5, and 11, then evaluate its integral at 10
        >>> integral_evaluation = logistic_integral(100, 5, 11)
        >>> print(integral_evaluation['evaluation'](10))
        0.1343
    Generate the integral of a logistic function with all inputs set to 0, then display its coefficients
        >>> integral_zeroes = logistic_integral(0, 0, 0)
        >>> print(integral_zeroes['constants'])
        [1.0, 0.0001, 0.0001]
    """
    # Handle input errors
    three_scalars(first_constant, second_constant, third_constant)
    positive_integer(precision)
    coefficients = no_zeroes([first_constant, second_constant, third_constant],
                             precision)

    # Create constants
    integral_coefficients = [
        coefficients[0] / coefficients[1], coefficients[1], coefficients[2]
    ]
    constants = rounded_list(integral_coefficients, precision)

    # Create evaluation
    def logistic_evaluation(variable):
        evaluation = constants[0] * log(
            abs(exp(constants[1] * (variable - constants[2])) + 1))
        rounded_evaluation = rounded_value(evaluation, precision)
        return rounded_evaluation

    # Package constants and evaluation in single dictionary
    results = {'constants': constants, 'evaluation': logistic_evaluation}
    return results
示例#9
0
def generate_elements(initial_value, periodic_unit, precision=4):
    """
    Generates a vector containing an initial numerical value, four additional numerical values created by incrementing the initial value by a periodic unit four times, and a string value for the general form of all values in the vector, made up of a multiple of the periodic unit added to the initial value; any negative periodic units will be converted their absolute values before any other evaluations occur

    Parameters
    ----------
    initial_value : int or float
        Starting value to adjust to fit into a range
    periodic_unit : int or float
        Unit by which the initial value should be incrementally increased or decreased to fit into a range
    precision : int, default=4
        Upper bound of range into which the initial value must be adjusted (final value should be less than or equal to maximum)

    Raises
    ------
    TypeError
        First and second arguments must be integers or floats
    ValueError
        Last argument must be a positive integer

    Returns
    -------
    generated_vector : list of float
        Vector containing five numerical values, each a set incremenent apart from one another, and a string value representing the general form of all numerical elements in the vector as well as any additional numerical elements that could be generated from it in the future

    See Also
    --------
    :func:`~regressions.statistics.ranges.shift_into_range`, :func:`~regressions.analyses.points.shifted_points_within_range`, :func:`~regressions.analyses.roots.sinusoidal.sinusoidal_roots`

    Notes
    -----
    - Initial value: :math:`v_i`
    - Periodic unit: :math:`\\lambda`
    - Set of all values derived from initial value and periodic unit: :math:`g = \\{ v \\mid v = v_i + \\lambda\\cdot{k} \\}`

        - :math:`k \\in \\mathbb{Z}`

    Examples
    --------
    Import `generate_elements` function from `regressions` library
        >>> from regressions.vectors.generate import generate_elements
    Generate a vector of elements based off an initial value of 3 and a periodic unit of 2
        >>> generated_vector_int = generate_elements(3, 2)
        >>> print(generated_vector_int)
        [3.0, 5.0, 7.0, 9.0, 11.0, '3.0 + 2.0k']
    Generate a vector of elements based off an initial value of 3 and a periodic unit of -2
        >>> generated_vector_neg = generate_elements(3, -2)
        >>> print(generated_vector_neg)
        [3.0, 5.0, 7.0, 9.0, 11.0, '3.0 + 2.0k']
    Generate a vector of elements based off an initial value of 17.23 and a periodic unit of 5.89
        >>> generated_vector_float = generate_elements(17.23, 5.89)
        >>> print(generated_vector_float)
        [17.23, 23.12, 29.01, 34.9, 40.79, '17.23 + 5.89k']
    """
    # Handle input errors
    two_scalars(initial_value, periodic_unit)
    positive_integer(precision)

    if periodic_unit < 0:
        periodic_unit = -1 * periodic_unit

    # Generate values from inputs
    first_value = initial_value + 1 * periodic_unit
    second_value = initial_value + 2 * periodic_unit
    third_value = initial_value + 3 * periodic_unit
    fourth_value = initial_value + 4 * periodic_unit

    # Store values in list
    values = [
        initial_value, first_value, second_value, third_value, fourth_value
    ]

    # Sort values
    sorted_values = sorted_list(values)

    # Round values
    rounded_values = rounded_list(sorted_values, precision)

    # Create general form
    rounded_periodic_unit = rounded_value(periodic_unit, precision)
    rounded_initial_value = rounded_value(initial_value, precision)
    general_form = str(rounded_initial_value) + ' + ' + str(
        rounded_periodic_unit) + 'k'

    # Store numerical values and general form in single list
    results = [*rounded_values, general_form]
    return results
示例#10
0
def cubic_integral(first_constant,
                   second_constant,
                   third_constant,
                   fourth_constant,
                   precision=4):
    """
    Generates the integral of a cubic function

    Parameters
    ----------
    first_constant : int or float
        Coefficient of the cubic term of the original cubic function; if zero, it will be converted to a small, non-zero decimal value (e.g., 0.0001)
    second_constant : int or float
        Coefficient of the quadratic term of the original cubic function; if zero, it will be converted to a small, non-zero decimal value (e.g., 0.0001)
    third_constant : int or float
        Coefficient of the linear term of the original cubic function; if zero, it will be converted to a small, non-zero decimal value (e.g., 0.0001)
    fourth_constant : int or float
        Coefficient of the constant term of the original cubic function; if zero, it will be converted to a small, non-zero decimal value (e.g., 0.0001)
    precision : int, default=4
        Maximum number of digits that can appear after the decimal place of the resultant roots

    Raises
    ------
    TypeError
        First four arguments must be integers or floats
    ValueError
        Last argument must be a positive integer

    Returns
    -------
    integral['constants'] : list of float
        Coefficients of the resultant integral
    integral['evaluation'] : func
        Function for evaluating the resultant integral at any float or integer argument
    
    See Also
    --------
    :func:`~regressions.analyses.equations.cubic.cubic_equation`, :func:`~regressions.analyses.derivatives.cubic.cubic_derivatives`, :func:`~regressions.analyses.roots.cubic.cubic_roots`, :func:`~regressions.models.cubic.cubic_model`

    Notes
    -----
    - Standard form of a cubic function: :math:`f(x) = a\\cdot{x^3} + b\\cdot{x^2} + c\\cdot{x} + d`
    - Integral of a cubic function: :math:`F(x) = \\frac{a}{4}\\cdot{x^4} + \\frac{b}{3}\\cdot{x^3} + \\frac{c}{2}\\cdot{x^2} + d\\cdot{x}`
    - |indefinite_integral|
    - |integration_formulas|

    Examples
    --------
    Import `cubic_integral` function from `regressions` library
        >>> from regressions.analyses.integrals.cubic import cubic_integral
    Generate the integral of a cubic function with coefficients 2, 3, 5, and 7, then display its coefficients
        >>> integral_constants = cubic_integral(2, 3, 5, 7)
        >>> print(integral_constants['constants'])
        [0.5, 1.0, 2.5, 7.0]
    Generate the integral of a cubic function with coefficients 7, -5, -3, and 2, then evaluate its integral at 10
        >>> integral_evaluation = cubic_integral(7, -5, -3, 2)
        >>> print(integral_evaluation['evaluation'](10))
        15703.3
    Generate the integral of a cubic function with all inputs set to 0, then display its coefficients
        >>> integral_zeroes = cubic_integral(0, 0, 0, 0)
        >>> print(integral_zeroes['constants'])
        [0.0001, 0.0001, 0.0001, 0.0001]
    """
    # Handle input errors
    four_scalars(first_constant, second_constant, third_constant,
                 fourth_constant)
    positive_integer(precision)
    coefficients = no_zeroes(
        [first_constant, second_constant, third_constant, fourth_constant],
        precision)

    # Generate constants
    integral_coefficients = [(1 / 4) * coefficients[0],
                             (1 / 3) * coefficients[1],
                             (1 / 2) * coefficients[2], coefficients[3]]
    constants = rounded_list(integral_coefficients, precision)

    # Create evaluation
    def cubic_evaluation(variable):
        evaluation = constants[0] * variable**4 + constants[
            1] * variable**3 + constants[2] * variable**2 + constants[
                3] * variable
        rounded_evaluation = rounded_value(evaluation, precision)
        return rounded_evaluation

    # Package constants and evaluation in single dictionary
    results = {'constants': constants, 'evaluation': cubic_evaluation}
    return results
示例#11
0
def linear_integral(first_constant, second_constant, precision = 4):
    """
    Generates the integral of a linear function

    Parameters
    ----------
    first_constant : int or float
        Coefficient of the linear term of the original linear function; if zero, it will be converted to a small, non-zero decimal value (e.g., 0.0001)
    second_constant : int or float
        Coefficient of the constant term of the original linear function; if zero, it will be converted to a small, non-zero decimal value (e.g., 0.0001)
    precision : int, default=4
        Maximum number of digits that can appear after the decimal place of the resultant roots

    Raises
    ------
    TypeError
        First two arguments must be integers or floats
    ValueError
        Last argument must be a positive integer

    Returns
    -------
    integral['constants'] : list of float
        Coefficients of the resultant integral
    integral['evaluation'] : func
        Function for evaluating the resultant integral at any float or integer argument

    See Also
    --------
    :func:`~regressions.analyses.equations.linear.linear_equation`, :func:`~regressions.analyses.derivatives.linear.linear_derivatives`, :func:`~regressions.analyses.roots.linear.linear_roots`, :func:`~regressions.models.linear.linear_model`

    Notes
    -----
    - Standard form of a linear function: :math:`f(x) = a\\cdot{x} + b`
    - Integral of a linear function: :math:`F(x) = \\frac{a}{2}\\cdot{x^2} + b\\cdot{x}`
    - |indefinite_integral|
    - |integration_formulas|

    Examples
    --------
    Import `linear_integral` function from `regressions` library
        >>> from regressions.analyses.integrals.linear import linear_integral
    Generate the integral of a linear function with coefficients 2 and 3, then display its coefficients
        >>> integral_constants = linear_integral(2, 3)
        >>> print(integral_constants['constants'])
        [1.0, 3.0]
    Generate the integral of a linear function with coefficients -2 and 3, then evaluate its integral at 10
        >>> integral_evaluation = linear_integral(-2, 3)
        >>> print(integral_evaluation['evaluation'](10))
        -70.0
    Generate the integral of a linear function with all inputs set to 0, then display its coefficients
        >>> integral_zeroes = linear_integral(0, 0)
        >>> print(integral_zeroes['constants'])
        [0.0001, 0.0001]
    """
    # Handle input errors
    two_scalars(first_constant, second_constant)
    positive_integer(precision)
    coefficients = no_zeroes([first_constant, second_constant], precision)

    # Create constants
    integral_coefficients = [(1/2) * coefficients[0], coefficients[1]]
    constants = rounded_list(integral_coefficients, precision)

    # Create evaluation
    def linear_evaluation(variable):
        evaluation = constants[0] * variable**2 + constants[1] * variable
        rounded_evaluation = rounded_value(evaluation, precision)
        return rounded_evaluation
    
    # Package constants and evaluation in single dictionary
    results = {
        'constants': constants,
        'evaluation': linear_evaluation
    }
    return results
示例#12
0
def exponential_derivatives(first_constant, second_constant, precision=4):
    """
    Calculates the first and second derivatives of an exponential function

    Parameters
    ----------
    first_constant : int or float
        Constant multiple of the original exponential function; if zero, it will be converted to a small, non-zero decimal value (e.g., 0.0001)
    second_constant : int or float
        Base rate of variable of the original exponential function; if zero, it will be converted to a small, non-zero decimal value (e.g., 0.0001)
    precision : int, default=4
        Maximum number of digits that can appear after the decimal place of the resultant roots

    Raises
    ------
    TypeError
        First two arguments must be integers or floats
    ValueError
        Last argument must be a positive integer

    Returns
    -------
    derivatives['first']['constants'] : list of float
        Coefficients of the resultant first derivative
    derivatives['first']['evaluation'] : func
        Function for evaluating the resultant first derivative at any float or integer argument
    derivatives['second']['constants'] : list of float
        Coefficients of the resultant second derivative
    derivatives['second']['evaluation'] : func
        Function for evaluating the resultant second derivative at any float or integer argument

    See Also
    --------
    :func:`~regressions.analyses.equations.exponential.exponential_equation`, :func:`~regressions.analyses.integrals.exponential.exponential_integral`, :func:`~regressions.analyses.roots.exponential.exponential_roots`, :func:`~regressions.models.exponential.exponential_model`

    Notes
    -----
    - Standard form of an exponential function: :math:`f(x) = a\\cdot{b^x}`
    - First derivative of an exponential function: :math:`f'(x) = a\\cdot{\\ln{b}\\cdot{b^x}}`
    - Second derivative of an exponential function: :math:`f''(x) = a\\cdot{\\ln^2{b}\\cdot{b^x}}`
    - |differentiation_formulas|
    - |exponential|

    Examples
    --------
    Import `exponential_derivatives` function from `regressions` library
        >>> from regressions.analyses.derivatives.exponential import exponential_derivatives
    Generate the derivatives of an exponential function with coefficients 2 and 3, then display the coefficients of its first and second derivatives
        >>> derivatives_constants = exponential_derivatives(2, 3)
        >>> print(derivatives_constants['first']['constants'])
        [2.1972, 3.0]
        >>> print(derivatives_constants['second']['constants'])
        [2.4139, 3.0]
    Generate the derivatives of an exponential function with coefficients -2 and 3, then evaluate its first and second derivatives at 10
        >>> derivatives_evaluation = exponential_derivatives(-2, 3)
        >>> print(derivatives_evaluation['first']['evaluation'](10))
        -129742.4628
        >>> print(derivatives_evaluation['second']['evaluation'](10))
        -142538.3811
    Generate the derivatives of an exponential function with all inputs set to 0, then display the coefficients of its first and second derivatives
        >>> derivatives_zeroes = exponential_derivatives(0, 0)
        >>> print(derivatives_zeroes['first']['constants'])
        [-0.0009, 0.0001]
        >>> print(derivatives_zeroes['second']['constants'])
        [0.0083, 0.0001]
    """
    # Handle input errors
    two_scalars(first_constant, second_constant)
    positive_integer(precision)
    coefficients = no_zeroes([first_constant, second_constant], precision)

    # Create first derivative
    first_coefficients = [
        coefficients[0] * log(abs(coefficients[1])), coefficients[1]
    ]
    first_constants = rounded_list(first_coefficients, precision)

    def first_derivative(variable):
        evaluation = first_constants[0] * first_constants[1]**variable
        rounded_evaluation = rounded_value(evaluation, precision)
        return rounded_evaluation

    first_dictionary = {
        'constants': first_constants,
        'evaluation': first_derivative
    }

    # Create second derivative
    second_coefficients = [
        first_constants[0] * log(abs(first_constants[1])), first_constants[1]
    ]
    second_constants = rounded_list(second_coefficients, precision)

    def second_derivative(variable):
        evaluation = second_constants[0] * second_constants[1]**variable
        rounded_evaluation = rounded_value(evaluation, precision)
        return rounded_evaluation

    second_dictionary = {
        'constants': second_constants,
        'evaluation': second_derivative
    }

    # Package both derivatives in single dictionary
    results = {'first': first_dictionary, 'second': second_dictionary}
    return results
示例#13
0
def sinusoidal_roots(first_constant, second_constant, third_constant, fourth_constant, precision = 4):
    """
    Calculates the roots of a sinusoidal function

    Parameters
    ----------
    first_constant : int or float
        Vertical stretch factor of the original sine function; if zero, it will be converted to a small, non-zero decimal value (e.g., 0.0001)
    second_constant : int or float
        Horizontal stretch factor of the original sine function; if zero, it will be converted to a small, non-zero decimal value (e.g., 0.0001)
    third_constant : int or float
        Horizontal shift of the original sine function; if zero, it will be converted to a small, non-zero decimal value (e.g., 0.0001)
    fourth_constant : int or float
        Vertical shift of the original sine function; if zero, it will be converted to a small, non-zero decimal value (e.g., 0.0001)
    precision : int, default=4
        Maximum number of digits that can appear after the decimal place of the resultant roots

    Raises
    ------
    TypeError
        First four arguments must be integers or floats
    ValueError
        Last argument must be a positive integer

    Returns
    -------
    roots : list of float or str
        List of the x-coordinates of the initial x-intercepts within two periods of the original function in float format, along with the general forms in string format that can be used to determine all other x-intercepts by plugging in any integer value for 'k' and evaluating; if the function never crosses the x-axis, then it will return a list of `None`

    See Also
    --------
    :func:`~regressions.analyses.equations.sinusoidal.sinusoidal_equation`, :func:`~regressions.analyses.derivatives.sinusoidal.sinusoidal_derivatives`, :func:`~regressions.analyses.integrals.sinusoidal.sinusoidal_integral`, :func:`~regressions.models.sinusoidal.sinusoidal_model`

    Notes
    -----
    - Standard form of a sinusoidal function: :math:`f(x) = a\\cdot{\\sin(b\\cdot(x - c))} + d`
    - Sinusoidal formula: :math:`x_0 = c + \\frac{1}{b}\\cdot{\\sin^{-1}(-\\frac{d}{a})} + \\frac{2\\pi}{b}\\cdot{k}`

        - :math:`\\text{if} -1 < -\\frac{d}{a} < 0 \\text{ or } 0 < -\\frac{d}{a} < 1, x_1 = c + \\frac{\\pi}{b} - \\frac{1}{b}\\cdot{\\sin^{-1}(-\\frac{d}{a})} + \\frac{2\\pi}{b}\\cdot{k}`
        - :math:`\\text{if} -\\frac{d}{a} = 0, x_1 = c - \\frac{\\pi}{b} + \\frac{2\\pi}{b}\\cdot{k}`
        - :math:`k \\in \\mathbb{Z}`

    Examples
    --------
    Import `sinusoidal_roots` function from `regressions` library
        >>> from regressions.analyses.roots.sinusoidal import sinusoidal_roots
    Calculate the roots of a sinusoidal function with coefficients 2, 3, 5, and 7
        >>> roots_first = sinusoidal_roots(2, 3, 5, 7)
        >>> print(roots_first)
        [None]
    Calculate the roots of a sinusoidal function with coefficients 7, -5, -3, and 2
        >>> roots_second = sinusoidal_roots(7, -5, -3, 2)
        >>> print(roots_second)
        [-8.7128, -7.9686, -7.4562, -6.712, -6.1995, -5.4553, -4.9429, -4.1987, -3.6863, -2.942, '-3.6863 + 1.2566k', '-2.942 + 1.2566k']
    Calculate the roots of a sinusoidal function with all inputs set to 0
        >>> roots_zeroes = sinusoidal_roots(0, 0, 0, 0)
        >>> print(roots_zeroes)
        [-15707.9632, 47123.8899, 109955.743, 172787.596, 235619.4491, '-15707.9632 + 62831.8531k']
    """
    # Handle input errors
    four_scalars(first_constant, second_constant, third_constant, fourth_constant)
    positive_integer(precision)
    coefficients = no_zeroes([first_constant, second_constant, third_constant, fourth_constant], precision)

    # Create list for roots
    roots = []

    # Identify key ratio
    ratio = -1 * coefficients[3] / coefficients[0]

    # Handle no roots
    if ratio > 1 or ratio < -1:
        roots = [None]
    
    # Handle multiple roots
    else:
        # Create intermediary variables
        radians = asin(ratio)
        periodic_radians = radians / coefficients[1]

        # Determine pertinent values
        periodic_unit = 2 * pi / coefficients[1]
        initial_value = coefficients[2] + periodic_radians
        roots = generate_elements(initial_value, periodic_unit, precision)
        
        # Handle roots that bounce on the x-axis
        if ratio == 1 or ratio == -1:
            pass
        
        # Handle roots that cross the x-axis
        else:
            # Determine supplementary values
            alternative_initial_value = coefficients[2] + pi / coefficients[1] - periodic_radians
            generated_elements = generate_elements(alternative_initial_value, periodic_unit, precision)
            
            # Add additional results to roots list
            roots.extend(generated_elements)
    
    # Separate numerical roots, string roots, and None results
    separated_roots = separate_elements(roots)
    numerical_roots = separated_roots['numerical']
    other_roots = separated_roots['other']
    
    # Sort numerical roots
    sorted_roots = sorted_list(numerical_roots)

    # Round numerical roots
    rounded_roots = rounded_list(sorted_roots, precision)
    
    # Sort other_roots
    sorted_other_roots = sorted_strings(other_roots)

    # Combine numerical and non-numerical roots
    result = rounded_roots + sorted_other_roots
    return result
示例#14
0
def cubic_roots(first_constant,
                second_constant,
                third_constant,
                fourth_constant,
                precision=4):
    """
    Calculates the roots of a cubic function

    Parameters
    ----------
    first_constant : int or float
        Coefficient of the cubic term of the original cubic function; if zero, it will be converted to a small, non-zero decimal value (e.g., 0.0001)
    second_constant : int or float
        Coefficient of the quadratic term of the original cubic function; if zero, it will be converted to a small, non-zero decimal value (e.g., 0.0001)
    third_constant : int or float
        Coefficient of the linear term of the original cubic function; if zero, it will be converted to a small, non-zero decimal value (e.g., 0.0001)
    fourth_constant : int or float
        Coefficient of the constant term of the original cubic function; if zero, it will be converted to a small, non-zero decimal value (e.g., 0.0001)
    precision : int, default=4
        Maximum number of digits that can appear after the decimal place of the resultant roots

    Raises
    ------
    TypeError
        First four arguments must be integers or floats
    ValueError
        Last argument must be a positive integer

    Returns
    -------
    roots : list of float
        List of the x-coordinates of all of the x-intercepts of the original function

    See Also
    --------
    :func:`~regressions.analyses.equations.cubic.cubic_equation`, :func:`~regressions.analyses.derivatives.cubic.cubic_derivatives`, :func:`~regressions.analyses.integrals.cubic.cubic_integral`, :func:`~regressions.models.cubic.cubic_model`

    Notes
    -----
    - Standard form of a cubic function: :math:`f(x) = a\\cdot{x^3} + b\\cdot{x^2} + c\\cdot{x} + d`
    - Cubic formula: :math:`x_k = -\\frac{1}{3a}\\cdot(b + \\xi^k\\cdot{\\eta} + \\frac{\\Delta_0}{\\xi^k\\cdot{\\eta}})`

        - :math:`\\Delta_0 = b^2 - 3ac`
        - :math:`\\Delta_1 = 2b^3 - 9abc +27a^2d`
        - :math:`\\xi = \\frac{-1 + \\sqrt{-3}}{2}`
        - :math:`\\eta = \\sqrt[3]{\\frac{\\Delta_1 \\pm \\sqrt{\\Delta_1^2 - 4\\Delta_0^3}}{2}}`
        - :math:`k \\in \\{ 0, 1, 2 \\}`
    
    - |cubic_formula|

    Examples
    --------
    Import `cubic_roots` function from `regressions` library
        >>> from regressions.analyses.roots.cubic import cubic_roots
    Calculate the roots of a cubic function with coefficients 2, 3, 5, and 7
        >>> roots_first = cubic_roots(2, 3, 5, 7)
        >>> print(roots_first)
        [-1.4455]
    Calculate the roots of a cubic function with coefficients 7, -5, -3, and 2
        >>> roots_second = cubic_roots(7, -5, -3, 2)
        >>> print(roots_second)
        [-0.6431, 0.551, 0.8064]
    Calculate the roots of a cubic function with all inputs set to 0
        >>> roots_zeroes = cubic_roots(0, 0, 0, 0)
        >>> print(roots_zeroes)
        [-1.0]
    """
    # Handle input errors
    four_scalars(first_constant, second_constant, third_constant,
                 fourth_constant)
    positive_integer(precision)
    coefficients = no_zeroes(
        [first_constant, second_constant, third_constant, fourth_constant],
        precision)

    # Create intermediary variables
    xi = (-1 + (-3)**(1 / 2)) / 2
    delta_first = coefficients[1]**2 - 3 * coefficients[0] * coefficients[2]
    delta_second = 2 * coefficients[1]**3 - 9 * coefficients[0] * coefficients[
        1] * coefficients[2] + 27 * coefficients[0]**2 * coefficients[3]
    discriminant = delta_second**2 - 4 * delta_first**3
    eta_first = ((delta_second + discriminant**(1 / 2)) / 2)**(1 / 3)
    eta_second = ((delta_second - discriminant**(1 / 2)) / 2)**(1 / 3)
    eta = 0
    if eta_first == 0:
        eta = eta_second
    else:
        eta = eta_first

    # Create roots
    roots = []
    first_root = (-1 /
                  (3 * coefficients[0])) * (coefficients[1] + eta * xi**0 +
                                            delta_first / (eta * xi**0))
    second_root = (-1 /
                   (3 * coefficients[0])) * (coefficients[1] + eta * xi**1 +
                                             delta_first / (eta * xi**1))
    third_root = (-1 /
                  (3 * coefficients[0])) * (coefficients[1] + eta * xi**2 +
                                            delta_first / (eta * xi**2))

    # Identify real and imaginary components of complex roots
    first_real = first_root.real
    second_real = second_root.real
    third_real = third_root.real
    first_imag = first_root.imag
    second_imag = second_root.imag
    third_imag = third_root.imag

    # Determine magnitudes of imaginary components
    size_first_imag = (first_imag**2)**(1 / 2)
    size_second_imag = (second_imag**2)**(1 / 2)
    size_third_imag = (third_imag**2)**(1 / 2)

    # Eliminate roots with large imaginary components
    if size_first_imag < 10**(-precision):
        first_root = first_real
        roots.append(first_root)
    if size_second_imag < 10**(-precision):
        second_root = second_real
        roots.append(second_root)
    if size_third_imag < 10**(-precision):
        third_root = third_real
        roots.append(third_root)

    # Eliminate duplicate roots
    unique_roots = list(set(roots))

    # Sort unique roots
    sorted_roots = sorted_list(unique_roots)

    # Round roots
    rounded_roots = rounded_list(sorted_roots, precision)

    # Return result
    result = rounded_roots
    return result
示例#15
0
def logistic_derivatives(first_constant,
                         second_constant,
                         third_constant,
                         precision=4):
    """
    Calculates the first and second derivatives of a logistic function

    Parameters
    ----------
    first_constant : int or float
        Carrying capacity of the original logistic function; if zero, it will be converted to a small, non-zero decimal value (e.g., 0.0001)
    second_constant : int or float
        Growth rate of the original logistic function; if zero, it will be converted to a small, non-zero decimal value (e.g., 0.0001)
    third_constant : int or float
        Value of the sigmoid's midpoint of the original logistic function; if zero, it will be converted to a small, non-zero decimal value (e.g., 0.0001)
    precision : int, default=4
        Maximum number of digits that can appear after the decimal place of the resultant roots

    Raises
    ------
    TypeError
        First three arguments must be integers or floats
    ValueError
        Last argument must be a positive integer

    Returns
    -------
    derivatives['first']['constants'] : list of float
        Coefficients of the resultant first derivative
    derivatives['first']['evaluation'] : func
        Function for evaluating the resultant first derivative at any float or integer argument
    derivatives['second']['constants'] : list of float
        Coefficients of the resultant second derivative
    derivatives['second']['evaluation'] : func
        Function for evaluating the resultant second derivative at any float or integer argument

    See Also
    --------
    :func:`~regressions.analyses.equations.logistic.logistic_equation`, :func:`~regressions.analyses.integrals.logistic.logistic_integral`, :func:`~regressions.analyses.roots.logistic.logistic_roots`, :func:`~regressions.models.logistic.logistic_model`

    Notes
    -----
    - Standard form of a logistic function: :math:`f(x) = \\frac{a}{1 + \\text{e}^{-b\\cdot(x - c)}}`
    - First derivative of a logistic function: :math:`f'(x) = \\frac{ab\\cdot{\\text{e}^{-b\\cdot(x - c)}}}{(1 + \\text{e}^{-b\\cdot(x - c)})^2}`
    - Second derivative of a logistic function: :math:`f''(x) = \\frac{2ab^2\\cdot{\\text{e}^{-2b\\cdot(x - c)}}}{(1 + \\text{e}^{-b\\cdot(x - c)})^3} - \\frac{ab^2\\cdot{\\text{e}^{-b\\cdot(x - c)}}}{(1 + \\text{e}^{-b\\cdot(x - c)})^2}`
    - |differentiation_formulas|
    - |chain_rule|
    - |exponential|

    Examples
    --------
    Import `logistic_derivatives` function from `regressions` library
        >>> from regressions.analyses.derivatives.logistic import logistic_derivatives
    Generate the derivatives of a logistic function with coefficients 2, 3, and 5, then display the coefficients of its first and second derivatives
        >>> derivatives_constants = logistic_derivatives(2, 3, 5)
        >>> print(derivatives_constants['first']['constants'])
        [6.0, 3.0, 5.0]
        >>> print(derivatives_constants['second']['constants'])
        [18.0, 3.0, 5.0]
    Generate the derivatives of a logistic function with coefficients 100, 5, and 11, then evaluate its first and second derivatives at 10
        >>> derivatives_evaluation = logistic_derivatives(100, 5, 11)
        >>> print(derivatives_evaluation['first']['evaluation'](10))
        3.324
        >>> print(derivatives_evaluation['second']['evaluation'](10))
        16.3977
    Generate the derivatives of a logistic function with all inputs set to 0, then display the coefficients of its first and second derivatives
        >>> derivatives_zeroes = logistic_derivatives(0, 0, 0)
        >>> print(derivatives_zeroes['first']['constants'])
        [0.0001, 0.0001, 0.0001]
        >>> print(derivatives_zeroes['second']['constants'])
        [0.0001, 0.0001, 0.0001]
    """
    # Handle input errors
    three_scalars(first_constant, second_constant, third_constant)
    positive_integer(precision)
    coefficients = no_zeroes([first_constant, second_constant, third_constant],
                             precision)

    # Create first derivative
    first_coefficients = [
        coefficients[0] * coefficients[1], coefficients[1], coefficients[2]
    ]
    first_constants = rounded_list(first_coefficients, precision)

    def first_derivative(variable):
        exponential = exp(-1 * first_constants[1] *
                          (variable - first_constants[2]))
        evaluation = first_constants[0] * exponential * (1 + exponential)**(-2)
        rounded_evaluation = rounded_value(evaluation, precision)
        return rounded_evaluation

    first_dictionary = {
        'constants': first_constants,
        'evaluation': first_derivative
    }

    # Create second derivative
    second_coefficients = [
        first_constants[0] * first_constants[1], first_constants[1],
        first_constants[2]
    ]
    second_constants = rounded_list(second_coefficients, precision)

    def second_derivative(variable):
        exponential = exp(-1 * second_constants[1] *
                          (variable - second_constants[2]))
        evaluation = second_constants[0] * exponential * (1 + exponential)**(
            -2) * (2 * exponential / (1 + exponential) - 1)
        rounded_evaluation = rounded_value(evaluation, precision)
        return rounded_evaluation

    second_dictionary = {
        'constants': second_constants,
        'evaluation': second_derivative
    }

    # Package both derivatives in single dictionary
    results = {'first': first_dictionary, 'second': second_dictionary}
    return results
示例#16
0
def system_solution(matrix_one, matrix_two, precision=4):
    """
    Solves a system of equations using matrices (independent matrix multiplied by resultant matrix equals dependent matrix)

    Parameters
    ----------
    matrix_one : list of lists of int or float
        List of lists of numbers representing the independent matrix of a system of equations
    matrix_two : list of lists of int or float
        List of lists of numbers representing the dependent matrix of a system of equations
    precision : int, default=4
        Maximum number of digits that can appear after the decimal place of the results

    Raises
    ------
    TypeError
        First and second arguments must be 2-dimensional lists
    TypeError
        Elements nested within first and second arguments must be integers or floats
    ValueError
        First and second arguments must contain the same amount of lists
    ValueError
        Last argument must be a positive integer
    
    Returns
    -------
    solution : list of float
        Row vector of coefficients that if expressed as a column vector would satisfy the equation

    See Also
    --------
    :func:`~regressions.matrices.multiplication.matrix_product`, :func:`~regressions.matrices.transpose.transposed_matrix`, :func:`~regressions.matrices.determinant.linear_determinant`, :func:`~regressions.matrices.inverse.inverse_matrix`

    Notes
    -----
    - Independent matrix: :math:`\\mathbf{A} = \\begin{bmatrix} a_{1,1} & a_{1,2} & \\cdots & a_{1,n} \\\\ a_{2,1} & a_{2,2} & \\cdots & a_{2,n} \\\\ \\cdots & \\cdots & \\cdots & \\cdots \\\\ a_{m,1} & a_{m,2} & \\cdots & a_{m,n} \\end{bmatrix}`
    - Dependent matrix: :math:`\\mathbf{B} = \\begin{bmatrix} b_{1,1} \\\\ b_{2,1} \\\\ \\cdots \\\\ b_{m,1} \\end{bmatrix}`
    - Variable matrix: :math:`\\mathbf{X} = \\begin{bmatrix} x_{1,1} \\\\ x_{2,1} \\\\ \\cdots \\\\ x_{m,1} \\end{bmatrix}`
    - System of equations in terms of matrices: :math:`\\mathbf{A}\\cdot{\\mathbf{X}} = \\mathbf{B}`
    - Solution of system of equations: :math:`\\mathbf{X} = \\mathbf{A}^{-1}\\cdot{\\mathbf{B}}`
    - |solve|

    Examples
    --------
    Import `system_solution` function from `regressions` library
        >>> from regressions.matrices.solve import system_solution
    Solve the system that has an independent matrix of [[2, 3], [1, -1]] and a dependent matrix of [[5], [1]]
        >>> solution_2values = system_solution([[2, 3], [1, -1]], [[5], [1]])
        >>> print(solution_2values)
        [1.6, 0.6]
    Solve the system that has an independent matrix of [[1, -2, 3], [-4, 5, -6], [7, -8, 9], [-10, 11, 12]] and a dependent matrix of [[2], [-3], [5], [-7]]
        >>> solution_3values = system_solution([[1, -2, 3], [-4, 5, -6], [7, -8, 9], [-10, 11, 12]], [[2], [-3], [5], [-7]])
        >>> print(solution_3values)
        [-0.8611, -1.3889, -0.0278]
    """
    # Handle input errors
    compare_rows(matrix_one, matrix_two)
    positive_integer(precision)

    # Multiply inverse of first matrix by second matrix
    transposition = transposed_matrix(matrix_one)
    product = matrix_product(transposition, matrix_one)
    inversion = inverse_matrix(product)
    second_product = matrix_product(inversion, transposition)
    solution_column = matrix_product(second_product, matrix_two)

    # Convert solution from a column vector into a row vector
    solution = single_dimension(solution_column, 1)

    # Round result
    result = rounded_list(solution, precision)
    return result