Example #1
0
def logistic_roots_initial_value(first_constant,
                                 second_constant,
                                 third_constant,
                                 initial_value,
                                 precision=4):
    # Handle input errors
    four_scalars(first_constant, second_constant, third_constant,
                 initial_value)
    positive_integer(precision)

    # Create list to return
    result = []

    # Create pivot variable
    log_argument = first_constant / initial_value - 1

    # Circumvent logarithm of zero
    if log_argument == 0:
        log_argument = 10**(-precision)

    # Create intermediary variables
    numerator = log(abs(log_argument))
    denominator = second_constant
    ratio = numerator / denominator

    # Determine root given an initial value
    root = third_constant - ratio

    # Round root
    rounded_root = rounded_value(root, precision)

    # Return result
    result.append(rounded_root)
    return result
Example #2
0
def quadratic_roots_derivative_initial_value(first_constant,
                                             second_constant,
                                             third_constant,
                                             initial_value,
                                             precision=4):
    # Handle input errors
    four_scalars(first_constant, second_constant, third_constant,
                 initial_value)
    positive_integer(precision)

    # Determine roots of derivative given an initial value
    result = linear_roots(2 * first_constant, second_constant - initial_value,
                          precision)
    return result
Example #3
0
 def test_four_scalars_integer_float_whole_positive(self):
     four_scalars_integer_float_whole_positive = four_scalars(
         good_integer, good_float, good_whole, good_positive)
     self.assertEqual(
         four_scalars_integer_float_whole_positive,
         'First, second, third, and fourth arguments are all integers or floats'
     )
def sinusoidal_roots_second_derivative(first_constant, second_constant, third_constant, fourth_constant, precision = 4):
    # Handle input errors
    four_scalars(first_constant, second_constant, third_constant, fourth_constant)
    positive_integer(precision)

    # Generate coefficients of second derivative
    constants = sinusoidal_derivatives(first_constant, second_constant, third_constant, fourth_constant)['second']['constants']

    # Create intermediary variables
    periodic_unit = pi / constants[1]
    initial_value = constants[2]

    # Generate roots based on criteria
    generated_roots = generate_elements(initial_value, periodic_unit, precision)

    # Return result
    result = generated_roots
    return result
Example #5
0
def cubic_roots_second_derivative(first_constant,
                                  second_constant,
                                  third_constant,
                                  fourth_constant,
                                  precision=4):
    # Handle input errors
    four_scalars(first_constant, second_constant, third_constant,
                 fourth_constant)
    positive_integer(precision)

    # Generate coefficients of second derivative
    constants = cubic_derivatives(first_constant, second_constant,
                                  third_constant,
                                  fourth_constant)['second']['constants']

    # Determine roots of second derivative
    result = linear_roots(*constants, precision)
    return result
Example #6
0
def logistic_roots_derivative_initial_value(first_constant,
                                            second_constant,
                                            third_constant,
                                            initial_value,
                                            precision=4):
    # Handle input errors
    four_scalars(first_constant, second_constant, third_constant,
                 initial_value)
    positive_integer(precision)

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

    # Determine quadratic roots of derivative given an initial value
    intermediary_roots = quadratic_roots(
        initial_value, 2 * initial_value - first_constant * second_constant,
        initial_value, precision)

    # Handle no roots
    if intermediary_roots[0] == None:
        roots.append(None)

    # Convert quadratic roots using logarithms
    else:
        for intermediary in intermediary_roots:
            if intermediary == 0:
                intermediary = 10**(-precision)
            root = third_constant - log(abs(intermediary)) / second_constant
            rounded_root = rounded_value(root, precision)
            roots.append(rounded_root)

    # Sort roots
    sorted_roots = sorted_list(roots)

    # Return result
    result.extend(sorted_roots)
    return result
Example #7
0
def sinusoidal_equation(first_constant, second_constant, third_constant, fourth_constant, precision = 4):
    """
    Generates a sinusoidal function to provide evaluations at variable inputs

    Parameters
    ----------
    first_constant : int or float
        Vertical stretch factor of the resultant 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 resultant 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 resultant 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 resultant 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
    -------
    evaluation : func
        Function for evaluating a sinusoidal equation when passed any integer or float argument

    See Also
    --------
    :func:`~regressions.analyses.derivatives.sinusoidal.sinusoidal_derivatives`, :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`

        - Period of function: :math:`\\frac{2\\pi}{|b|}`
        - Amplitude of function: :math:`|a|`

    - |sine_functions|

    Examples
    --------
    Import `sinusoidal_equation` function from `regressions` library
        >>> from regressions.analyses.equations.sinusoidal import sinusoidal_equation
    Create a sinusoidal function with coefficients 2, 3, 5, and 7, then evaluate it at 10
        >>> evaluation_first = sinusoidal_equation(2, 3, 5, 7)
        >>> print(evaluation_first(10))
        8.3006
    Create a sinusoidal function with coefficients 7, -5, -3, and 2, then evaluate it at 10
        >>> evaluation_second = sinusoidal_equation(7, -5, -3, 2)
        >>> print(evaluation_second(10))
        -3.7878
    Create a sinusoidal function with all inputs set to 0, then evaluate it at 10
        >>> evaluation_zero = sinusoidal_equation(0, 0, 0, 0)
        >>> print(evaluation_zero(10))
        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 evaluation
    def sinusoidal_evaluation(variable):
        evaluation = coefficients[0] * sin(coefficients[1] * (variable - coefficients[2])) + coefficients[3]
        result = rounded_value(evaluation, precision)
        return result
    return sinusoidal_evaluation
Example #8
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
Example #9
0
def cubic_equation(first_constant,
                   second_constant,
                   third_constant,
                   fourth_constant,
                   precision=4):
    """
    Generates a cubic function to provide evaluations at variable inputs

    Parameters
    ----------
    first_constant : int or float
        Coefficient of the cubic term of the resultant 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 resultant 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 resultant 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 resultant 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
    -------
    evaluation : func
        Function for evaluating a cubic equation when passed any integer or float argument
    
    See Also
    --------
    :func:`~regressions.analyses.derivatives.cubic.cubic_derivatives`, :func:`~regressions.analyses.integrals.cubic.cubic_integral`, :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`
    - |cubic_functions|

    Examples
    --------
    Import `cubic_equation` function from `regressions` library
        >>> from regressions.analyses.equations.cubic import cubic_equation
    Create a cubic function with coefficients 2, 3, 5, and 7, then evaluate it at 10
        >>> evaluation_first = cubic_equation(2, 3, 5, 7)
        >>> print(evaluation_first(10))
        2357.0
    Create a cubic function with coefficients 7, -5, -3, and 2, then evaluate it at 10
        >>> evaluation_second = cubic_equation(7, -5, -3, 2)
        >>> print(evaluation_second(10))
        6472.0
    Create a cubic function with all inputs set to 0, then evaluate it at 10
        >>> evaluation_zero = cubic_equation(0, 0, 0, 0)
        >>> print(evaluation_zero(10))
        0.1111
    """
    # 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 evaluation
    def cubic_evaluation(variable):
        evaluation = coefficients[0] * variable**3 + coefficients[
            1] * variable**2 + coefficients[2] * variable + coefficients[3]
        result = rounded_value(evaluation, precision)
        return result

    return cubic_evaluation
Example #10
0
def shift_into_range(initial_value, periodic_unit, minimum, maximum):
    """
    Adjusts an intial value to one within a particular range by increasing or decreasing its value by a specified unit

    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
    minimum : int or float
        Lower bound of range into which the initial value must be adjusted (final value should be greater than or equal to minimum)
    maximum : int or float
        Upper bound of range into which the initial value must be adjusted (final value should be less than or equal to maximum)

    Raises
    ------
    TypeError
        Arguments must be integers or floats
    ValueError
        Third argument must be less than or equal to fourth argument

    Returns
    -------
    final_value : float
        Value within range that only differs from the initial value by a an integral multiple of the periodic unit

    See Also
    --------
    :func:`~regressions.analyses.points.shifted_points_within_range`, :func:`~regressions.analyses.mean_values.mean_values_derivative`, :func:`~regressions.analyses.mean_values.mean_values_integral`

    Notes
    -----
    - Initial value: :math:`v_i`
    - Periodic unit: :math:`\\lambda`
    - Lower bound of range: :math:`b_l`
    - Upper bound of range: :math:`b_u`
    - 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}`
    
    - Final value: :math:`v_f \\geq b_l \\cap v_f \\leq b_u \\cap v_f \\in g`

    Examples
    --------
    Import `shift_into_range` function from `regressions` library
        >>> from regressions.statistics.ranges import shift_into_range
    Adjust the number 7 to a value between 20 and 30, based on a periodic unit of 8
        >>> final_value_int = shift_into_range(7, 8, 20, 30)
        >>> print(final_value_int)
        23.0
    Adjust the number 524.62 to a value between 138.29 and 213.86, based on a periodic unit of 23.91
        >>> final_value_float = shift_into_range(524.62, 23.91, 138.29, 213.86)
        >>> print(final_value_float)
        213.78999999999974
    """
    # Handle input errors
    four_scalars(initial_value, periodic_unit, minimum, maximum)
    compare_scalars(minimum, maximum, 'third', 'fourth')

    # Set input value to alternative value
    alternative_initial_value = initial_value
    
    # Handle positive periodic units
    if periodic_unit > 0:
        # Decrease value till below maximum
        while alternative_initial_value > maximum:
            alternative_initial_value -= periodic_unit

        # Increase value till above minimum
        while alternative_initial_value < minimum:
            alternative_initial_value += periodic_unit
    
    # Handle negative periodic units
    else:
        # Decrease value till below maximum
        while alternative_initial_value > maximum:
            alternative_initial_value += periodic_unit

        # Increase value till above minimum
        while alternative_initial_value < minimum:
            alternative_initial_value -= periodic_unit

    # Convert final value to float
    final_value = float(alternative_initial_value)
    return final_value
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
Example #12
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
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
Example #14
0
 def test_four_scalars_integer_float_whole_string_raises(self):
     with self.assertRaises(Exception) as context:
         four_scalars(good_integer, good_float, good_whole, bad_scalar)
     self.assertEqual(type(context.exception), TypeError)
     self.assertEqual(str(context.exception),
                      'Fourth argument must be an integer or a float')
Example #15
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
Example #16
0
def cubic_derivatives(first_constant,
                      second_constant,
                      third_constant,
                      fourth_constant,
                      precision=4):
    """
    Calculates the first and second derivatives 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
    -------
    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.cubic.cubic_equation`, :func:`~regressions.analyses.integrals.cubic.cubic_integral`, :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`
    - First derivative of a cubic function: :math:`f'(x) = 3a\\cdot{x^2} + 2b\\cdot{x} + c`
    - Second derivative of a cubic function: :math:`f''(x) = 6a\\cdot{x} + 2b`
    - |differentiation_formulas|

    Examples
    --------
    Import `cubic_derivatives` function from `regressions` library
        >>> from regressions.analyses.derivatives.cubic import cubic_derivatives
    Generate the derivatives of a cubic function with coefficients 2, 3, 5, and 7, then display the coefficients of its first and second derivatives
        >>> derivatives_constants = cubic_derivatives(2, 3, 5, 7)
        >>> print(derivatives_constants['first']['constants'])
        [6.0, 6.0, 5.0]
        >>> print(derivatives_constants['second']['constants'])
        [12.0, 6.0]
    Generate the derivatives of a cubic function with coefficients 7, -5, -3, and 2, then evaluate its first and second derivatives at 10
        >>> derivatives_evaluation = cubic_derivatives(7, -5, -3, 2)
        >>> print(derivatives_evaluation['first']['evaluation'](10))
        1997.0
        >>> print(derivatives_evaluation['second']['evaluation'](10))
        410.0
    Generate the derivatives of a cubic function with all inputs set to 0, then display the coefficients of its first and second derivatives
        >>> derivatives_zeroes = cubic_derivatives(0, 0, 0, 0)
        >>> print(derivatives_zeroes['first']['constants'])
        [0.0003, 0.0002, 0.0001]
        >>> print(derivatives_zeroes['second']['constants'])
        [0.0006, 0.0002]
    """
    # 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_constants = [
        3 * coefficients[0], 2 * coefficients[1], coefficients[2]
    ]

    def first_derivative(variable):
        evaluation = first_constants[0] * variable**2 + 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_constants = [2 * first_constants[0], first_constants[1]]

    def second_derivative(variable):
        evaluation = second_constants[0] * variable + second_constants[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