def a_vector_OLS_and_LP(m_dict, bounds, boundedness, term_limit, term_lower_bound, fit_method, alpha, diff_error=0.001, diff_step=0.001):
    " Main workhorse function of pymetalog package.\n        Called during metalog.__init__ method call.\n\n    Args:\n        m_dict (:obj:`dict` with keys ['params', 'dataValues', 'Y']): Initialized output_dict variable from metalog class.\n            - m_dict['params']: (:obj:`dict` with keys ['bounds', 'boundedness', 'term_limit', 'term_lower_bound', 'step_len', 'fit_method']):\n                * 'bounds': metalog.bounds\n                * 'boundedness': metalog.boundedness\n                * 'term_limit': metalog.term_limit\n                * 'term_lower_bound': metalog.term_lower_bound\n                * 'step_len': metalog.step_len\n                * 'fit_method': metalog.fit_method\n\n            - m_dict['dataValues']: (:obj:`pandas.DataFrame` with columns ['x','probs','z']  of type numeric):\n                * 'x': metalog.x\n                * 'probs': metalog.probs\n                * 'z': column calculated in metalog.append_zvector method\n                    - depends on metalog.boundedness attribute\n                    - metalog.boundedness = 'u':\n                        * 'z' = metalog.x\n                    - metalog.boundedness = 'sl':\n                        * 'z' = log( (metalog.x-lower_bound) )\n                    - metalog.boundedness = 'su':\n                        * 'z' = = log( (upper_bound-metalog.x) )\n                    - metalog.boundedness = 'b':\n                        * 'z' = log( (metalog.x-lower_bound) / (upper_bound-metalog.x) )\n\n            - m_dict['Y']: (:obj:`pandas.DataFrame` with columns ['y1','y2','y3','y4', ... ,'yn']  of type numeric):\n                * 'y1': numpy.array of ones with length equal to len(x)\n                * 'y2': numpy.array of numeric values equal to the term attached to s in the logistic quantile function np.log(m_dict['dataValues']['probs'] / (1 - m_dict['dataValues']['probs']))\n                * 'y3': numpy.array of numeric values (m_dict['dataValues']['probs'] - 0.5) * m_dict['Y']['y2']\n                * 'y4': numpy.array of numeric values m_dict['Y']['y4'] = m_dict['dataValues']['probs'] - 0.5\n                * 'yn': numpy.array of numeric values:\n                    - if n in 'yn' is odd,\n                        m_dict['Y']['yn'] = m_dict['Y']['y4']**(int(i//2))\n                    - if n in 'yn' is even,\n                        zn = 'y' + str(n-1)\n                        m_dict['Y'][yn] = m_dict['Y']['y2'] * m_dict['Y'][zn]\n\n        bounds (:obj:`list`): Upper and lower limits to filter the data with before calculating metalog quantiles/pdfs.\n            - should be set in conjunction with the `boundedness` parameter\n\n        boundedness (:obj:`str`): String that is used to specify the type of metalog to fit.\n            - must be in set ('u','sl','su','b')\n            - Default: 'u'\n                * Fits an unbounded metalog\n            - 'sl' fits a strictly lower bounded metalog\n                * len(bounds) must == 1\n            - 'su' fits a strictly upper bounded metalog\n                * len(bounds) must == 1\n            - 'b' fits a upper/lower bounded metalog\n                * len(bounds) must == 2\n                * bounds[1] must be > bounds[0]\n\n        term_limit (:obj:`int`): The upper limit of the range of metalog terms to use to fit the data.\n            - strictly > term_lower_bound\n            - in range [3,30]\n\n        term_lower_bound (:obj:`int`): The lower limit of the range of metalog terms to use to fit the data.\n            - strictly < term_limit\n            - in range [2,29]\n\n        fit_method (:obj:`str`): Fit method to use to fit metalog distribution.\n            - must be in set ('any','OLS','LP','MLE')\n            - Default: 'any'\n                * first tries 'OLS' method than 'LP'\n            - 'OLS' only tries to fit by solving directly for a coefficients using ordinary least squares method\n            - 'LP' only tries to estimate fit using simplex linear program optimization routine\n            - 'MLE' first tries 'OLS' method than falls back to a maximum likelihood estimation routine\n\n        alpha (:obj:`float`, optional): Regularization term to add to OLS fit\n            - strictly >= 0.\n            - should be set in conjunction with `penalty` parameter\n            - Default: 0. (no regularization, OLS)\n\n        diff_error (:obj:`float`, optional): Value used to in scipy.optimize.linprog method call\n                                             to init the array of values representing the\n                                             upper-bound of each inequality constraint (row) in A_ub.\n            - #TODO: Insert maths\n\n        diff_step (:obj:`float`, optional): Value passed to `step_len` parameter in support.py diffMatMetalog method call\n                                             defines the bin width for the Reimann sum of the differences differentiation method\n            - diffMatMetalog differentiates the metalog pdf\n                * Differentiation reference: https://math.stackexchange.com/a/313135\n    Returns:\n        m_dict: (:obj:`dict` with keys ['params', 'dataValues', 'Y', 'A', 'M', 'Validation'])\n            - m_dict['A']: (:obj:`pandas.DataFrame` with columns ['a2','a3', ... ,'an'] of type numeric):\n                * a2, a3, ... , an are our a coefficients returned by the method specified in `fit_method`\n\n            - m_dict['M']: (:obj:`pandas.DataFrame` with columns 0:'pdf_1',1:'cdf_1',2:'pdf_2',3:'cdf_2',\n                            ...,((2*(term_limit-term_lower_bound))+1)-1:'pdf_n',\n                                ((2*(term_limit-term_lower_bound))+1):'cdf_n'\n                            where n is the total number of metalog fits determined by (term_limit-term_lower_bound)+1\n                            )\n                * pdf_1, pdf_2, ... , pdf_n are the metalog pdfs returned by pdf_quantile_builder.pdfMetalog method\n                * cdf_1, cdf_2, ... , cdf_n are the metalog quantiles returned by pdf_quantile_builder.quantileMetalog method\n            \n            - m_dict['y']: (:obj: `numpy.ndarray` of type float):\n                * Array of bin widths for both the pdf_n and cdf_n\n\n            - m_dict['Validation']: (:obj:`pandas.DataFrame` with columns ['term', 'valid', 'method'] of type str):\n                * 'term': each metalog estimation given a number of terms\n                * 'valid': boolean flag indicating if the metalog estimation was valid or not\n                * 'method': a string indicating which method was used for the metalog estimation\n\n    "
    A = pd.DataFrame()
    c_a_names = []
    c_m_names = []
    Mh = pd.DataFrame()
    Validation = pd.DataFrame()
    df_MH_temp_list = list()
    df_A_temp_list = list()
    df_Validation_temp_list = list()
    for i in range(term_lower_bound, (term_limit + 1)):
        Y = m_dict['Y'].iloc[:, 0:i]
        eye = np.eye(Y.shape[1])
        z = m_dict['dataValues']['z']
        y = m_dict['dataValues']['probs']
        step_len = m_dict['params']['step_len']
        methodFit = 'OLS'
        a_name = ('a' + str(i))
        m_name = ('m' + str(i))
        M_name = ('M' + str(i))
        c_m_names = np.append(c_m_names, [m_name, M_name])
        c_a_names = np.append(c_a_names, a_name)
        if ((fit_method == 'any') or (fit_method == 'MLE')):
            try:
                temp = np.dot(np.dot(np.linalg.inv((np.dot(Y.T, Y) + (alpha * eye))), Y.T), z)
            except:
                temp = a_vector_LP(m_dict, term_limit=i, term_lower_bound=i, diff_error=diff_error, diff_step=diff_step)
                methodFit = 'Linear Program'
        if (fit_method == 'OLS'):
            try:
                temp = np.dot(np.dot(np.linalg.inv((np.dot(Y.T, Y) + (alpha * eye))), Y.T), z)
            except:
                raise RuntimeError('OLS was unable to solve infeasible or poorly formulated problem')
        if (fit_method == 'LP'):
            temp = a_vector_LP(m_dict, term_limit=i, term_lower_bound=i, diff_error=diff_error, diff_step=diff_step)
            methodFit = 'Linear Program'
        if (fit_method == 'MLE'):
            temp = a_vector_MLE(temp, y, i, m_dict, bounds, boundedness)
        temp = np.append(temp, np.zeros((term_limit - i)))
        if (len(z) < 100):
            y2 = np.linspace(step_len, (1 - step_len), int(((1 - step_len) / step_len)))
            tailstep = (step_len / 10)
            y1 = np.linspace(tailstep, (min(y2) - tailstep), int(((min(y2) - tailstep) / tailstep)))
            y3 = np.linspace((max(y2) + tailstep), (max(y2) + (tailstep * 9)), int(((tailstep * 9) / tailstep)))
            y = np.hstack((y1, y2, y3))
        temp_dict = pdf_quantile_builder(temp, y=y, term_limit=i, bounds=bounds, boundedness=boundedness)
        if ((temp_dict['valid'] == 'no') and (fit_method != 'OLS')):
            temp = a_vector_LP(m_dict, term_limit=i, term_lower_bound=i, diff_error=diff_error, diff_step=diff_step)
            temp = np.append(temp, np.zeros((term_limit - i)))
            methodFit = 'Linear Program'
            temp_dict = pdf_quantile_builder(temp, y=y, term_limit=i, bounds=bounds, boundedness=boundedness)
        df_MH_temp_list.append(pd.DataFrame(temp_dict['m']))
        df_MH_temp_list.append(pd.DataFrame(temp_dict['M']))
        df_A_temp_list.append(pd.DataFrame(temp))
        tempValidation = pd.DataFrame(data={'term': [i], 'valid': [temp_dict['valid']], 'method': [methodFit]})
        df_Validation_temp_list.append(tempValidation)
    Validation = pd.concat(df_Validation_temp_list, axis=0)
    Mh = pd.concat(df_MH_temp_list, axis=1)
    A = pd.concat(df_A_temp_list, axis=1)
    A.columns = c_a_names
    Mh.columns = c_m_names
    m_dict['A'] = A
    m_dict['M'] = Mh
    m_dict['M']['y'] = temp_dict['y']
    m_dict['Validation'] = Validation
    A = np.column_stack((np.repeat(1.0, len(A)), A))
    Est = np.dot(m_dict['Y'], A)
    ncols = A.shape[1]
    Z = np.column_stack((np.array(m_dict['dataValues']['z']), np.repeat(m_dict['dataValues']['z'].values, (ncols - 1)).reshape(len(m_dict['dataValues']['z']), (ncols - 1))))
    m_dict['square_residual_error'] = ((Z - Est) ** 2).sum(axis=1)
    return m_dict
Main workhorse function of pymetalog package.
    Called during metalog.__init__ method call.

Args:
    m_dict (:obj:`dict` with keys ['params', 'dataValues', 'Y']): Initialized output_dict variable from metalog class.
        - m_dict['params']: (:obj:`dict` with keys ['bounds', 'boundedness', 'term_limit', 'term_lower_bound', 'step_len', 'fit_method']):
            * 'bounds': metalog.bounds
            * 'boundedness': metalog.boundedness
            * 'term_limit': metalog.term_limit
            * 'term_lower_bound': metalog.term_lower_bound
            * 'step_len': metalog.step_len
            * 'fit_method': metalog.fit_method

        - m_dict['dataValues']: (:obj:`pandas.DataFrame` with columns ['x','probs','z']  of type numeric):
            * 'x': metalog.x
            * 'probs': metalog.probs
            * 'z': column calculated in metalog.append_zvector method
                - depends on metalog.boundedness attribute
                - metalog.boundedness = 'u':
                    * 'z' = metalog.x
                - metalog.boundedness = 'sl':
                    * 'z' = log( (metalog.x-lower_bound) )
                - metalog.boundedness = 'su':
                    * 'z' = = log( (upper_bound-metalog.x) )
                - metalog.boundedness = 'b':
                    * 'z' = log( (metalog.x-lower_bound) / (upper_bound-metalog.x) )

        - m_dict['Y']: (:obj:`pandas.DataFrame` with columns ['y1','y2','y3','y4', ... ,'yn']  of type numeric):
            * 'y1': numpy.array of ones with length equal to len(x)
            * 'y2': numpy.array of numeric values equal to the term attached to s in the logistic quantile function np.log(m_dict['dataValues']['probs'] / (1 - m_dict['dataValues']['probs']))
            * 'y3': numpy.array of numeric values (m_dict['dataValues']['probs'] - 0.5) * m_dict['Y']['y2']
            * 'y4': numpy.array of numeric values m_dict['Y']['y4'] = m_dict['dataValues']['probs'] - 0.5
            * 'yn': numpy.array of numeric values:
                - if n in 'yn' is odd,
                    m_dict['Y']['yn'] = m_dict['Y']['y4']**(int(i//2))
                - if n in 'yn' is even,
                    zn = 'y' + str(n-1)
                    m_dict['Y'][yn] = m_dict['Y']['y2'] * m_dict['Y'][zn]

    bounds (:obj:`list`): Upper and lower limits to filter the data with before calculating metalog quantiles/pdfs.
        - should be set in conjunction with the `boundedness` parameter

    boundedness (:obj:`str`): String that is used to specify the type of metalog to fit.
        - must be in set ('u','sl','su','b')
        - Default: 'u'
            * Fits an unbounded metalog
        - 'sl' fits a strictly lower bounded metalog
            * len(bounds) must == 1
        - 'su' fits a strictly upper bounded metalog
            * len(bounds) must == 1
        - 'b' fits a upper/lower bounded metalog
            * len(bounds) must == 2
            * bounds[1] must be > bounds[0]

    term_limit (:obj:`int`): The upper limit of the range of metalog terms to use to fit the data.
        - strictly > term_lower_bound
        - in range [3,30]

    term_lower_bound (:obj:`int`): The lower limit of the range of metalog terms to use to fit the data.
        - strictly < term_limit
        - in range [2,29]

    fit_method (:obj:`str`): Fit method to use to fit metalog distribution.
        - must be in set ('any','OLS','LP','MLE')
        - Default: 'any'
            * first tries 'OLS' method than 'LP'
        - 'OLS' only tries to fit by solving directly for a coefficients using ordinary least squares method
        - 'LP' only tries to estimate fit using simplex linear program optimization routine
        - 'MLE' first tries 'OLS' method than falls back to a maximum likelihood estimation routine

    alpha (:obj:`float`, optional): Regularization term to add to OLS fit
        - strictly >= 0.
        - should be set in conjunction with `penalty` parameter
        - Default: 0. (no regularization, OLS)

    diff_error (:obj:`float`, optional): Value used to in scipy.optimize.linprog method call
                                         to init the array of values representing the
                                         upper-bound of each inequality constraint (row) in A_ub.
        - #TODO: Insert maths

    diff_step (:obj:`float`, optional): Value passed to `step_len` parameter in support.py diffMatMetalog method call
                                         defines the bin width for the Reimann sum of the differences differentiation method
        - diffMatMetalog differentiates the metalog pdf
            * Differentiation reference: https://math.stackexchange.com/a/313135
Returns:
    m_dict: (:obj:`dict` with keys ['params', 'dataValues', 'Y', 'A', 'M', 'Validation'])
        - m_dict['A']: (:obj:`pandas.DataFrame` with columns ['a2','a3', ... ,'an'] of type numeric):
            * a2, a3, ... , an are our a coefficients returned by the method specified in `fit_method`

        - m_dict['M']: (:obj:`pandas.DataFrame` with columns 0:'pdf_1',1:'cdf_1',2:'pdf_2',3:'cdf_2',
                        ...,((2*(term_limit-term_lower_bound))+1)-1:'pdf_n',
                            ((2*(term_limit-term_lower_bound))+1):'cdf_n'
                        where n is the total number of metalog fits determined by (term_limit-term_lower_bound)+1
                        )
            * pdf_1, pdf_2, ... , pdf_n are the metalog pdfs returned by pdf_quantile_builder.pdfMetalog method
            * cdf_1, cdf_2, ... , cdf_n are the metalog quantiles returned by pdf_quantile_builder.quantileMetalog method
        
        - m_dict['y']: (:obj: `numpy.ndarray` of type float):
            * Array of bin widths for both the pdf_n and cdf_n

        - m_dict['Validation']: (:obj:`pandas.DataFrame` with columns ['term', 'valid', 'method'] of type str):
            * 'term': each metalog estimation given a number of terms
            * 'valid': boolean flag indicating if the metalog estimation was valid or not
            * 'method': a string indicating which method was used for the metalog estimation
def a_vector_OLS_and_LP(m_dict, bounds, boundedness, term_limit, term_lower_bound, fit_method, alpha, diff_error=0.001, diff_step=0.001):
    " Main workhorse function of pymetalog package.\n        Called during metalog.__init__ method call.\n\n    Args:\n        m_dict (:obj:`dict` with keys ['params', 'dataValues', 'Y']): Initialized output_dict variable from metalog class.\n            - m_dict['params']: (:obj:`dict` with keys ['bounds', 'boundedness', 'term_limit', 'term_lower_bound', 'step_len', 'fit_method']):\n                * 'bounds': metalog.bounds\n                * 'boundedness': metalog.boundedness\n                * 'term_limit': metalog.term_limit\n                * 'term_lower_bound': metalog.term_lower_bound\n                * 'step_len': metalog.step_len\n                * 'fit_method': metalog.fit_method\n\n            - m_dict['dataValues']: (:obj:`pandas.DataFrame` with columns ['x','probs','z']  of type numeric):\n                * 'x': metalog.x\n                * 'probs': metalog.probs\n                * 'z': column calculated in metalog.append_zvector method\n                    - depends on metalog.boundedness attribute\n                    - metalog.boundedness = 'u':\n                        * 'z' = metalog.x\n                    - metalog.boundedness = 'sl':\n                        * 'z' = log( (metalog.x-lower_bound) )\n                    - metalog.boundedness = 'su':\n                        * 'z' = = log( (upper_bound-metalog.x) )\n                    - metalog.boundedness = 'b':\n                        * 'z' = log( (metalog.x-lower_bound) / (upper_bound-metalog.x) )\n\n            - m_dict['Y']: (:obj:`pandas.DataFrame` with columns ['y1','y2','y3','y4', ... ,'yn']  of type numeric):\n                * 'y1': numpy.array of ones with length equal to len(x)\n                * 'y2': numpy.array of numeric values equal to the term attached to s in the logistic quantile function np.log(m_dict['dataValues']['probs'] / (1 - m_dict['dataValues']['probs']))\n                * 'y3': numpy.array of numeric values (m_dict['dataValues']['probs'] - 0.5) * m_dict['Y']['y2']\n                * 'y4': numpy.array of numeric values m_dict['Y']['y4'] = m_dict['dataValues']['probs'] - 0.5\n                * 'yn': numpy.array of numeric values:\n                    - if n in 'yn' is odd,\n                        m_dict['Y']['yn'] = m_dict['Y']['y4']**(int(i//2))\n                    - if n in 'yn' is even,\n                        zn = 'y' + str(n-1)\n                        m_dict['Y'][yn] = m_dict['Y']['y2'] * m_dict['Y'][zn]\n\n        bounds (:obj:`list`): Upper and lower limits to filter the data with before calculating metalog quantiles/pdfs.\n            - should be set in conjunction with the `boundedness` parameter\n\n        boundedness (:obj:`str`): String that is used to specify the type of metalog to fit.\n            - must be in set ('u','sl','su','b')\n            - Default: 'u'\n                * Fits an unbounded metalog\n            - 'sl' fits a strictly lower bounded metalog\n                * len(bounds) must == 1\n            - 'su' fits a strictly upper bounded metalog\n                * len(bounds) must == 1\n            - 'b' fits a upper/lower bounded metalog\n                * len(bounds) must == 2\n                * bounds[1] must be > bounds[0]\n\n        term_limit (:obj:`int`): The upper limit of the range of metalog terms to use to fit the data.\n            - strictly > term_lower_bound\n            - in range [3,30]\n\n        term_lower_bound (:obj:`int`): The lower limit of the range of metalog terms to use to fit the data.\n            - strictly < term_limit\n            - in range [2,29]\n\n        fit_method (:obj:`str`): Fit method to use to fit metalog distribution.\n            - must be in set ('any','OLS','LP','MLE')\n            - Default: 'any'\n                * first tries 'OLS' method than 'LP'\n            - 'OLS' only tries to fit by solving directly for a coefficients using ordinary least squares method\n            - 'LP' only tries to estimate fit using simplex linear program optimization routine\n            - 'MLE' first tries 'OLS' method than falls back to a maximum likelihood estimation routine\n\n        alpha (:obj:`float`, optional): Regularization term to add to OLS fit\n            - strictly >= 0.\n            - should be set in conjunction with `penalty` parameter\n            - Default: 0. (no regularization, OLS)\n\n        diff_error (:obj:`float`, optional): Value used to in scipy.optimize.linprog method call\n                                             to init the array of values representing the\n                                             upper-bound of each inequality constraint (row) in A_ub.\n            - #TODO: Insert maths\n\n        diff_step (:obj:`float`, optional): Value passed to `step_len` parameter in support.py diffMatMetalog method call\n                                             defines the bin width for the Reimann sum of the differences differentiation method\n            - diffMatMetalog differentiates the metalog pdf\n                * Differentiation reference: https://math.stackexchange.com/a/313135\n    Returns:\n        m_dict: (:obj:`dict` with keys ['params', 'dataValues', 'Y', 'A', 'M', 'Validation'])\n            - m_dict['A']: (:obj:`pandas.DataFrame` with columns ['a2','a3', ... ,'an'] of type numeric):\n                * a2, a3, ... , an are our a coefficients returned by the method specified in `fit_method`\n\n            - m_dict['M']: (:obj:`pandas.DataFrame` with columns 0:'pdf_1',1:'cdf_1',2:'pdf_2',3:'cdf_2',\n                            ...,((2*(term_limit-term_lower_bound))+1)-1:'pdf_n',\n                                ((2*(term_limit-term_lower_bound))+1):'cdf_n'\n                            where n is the total number of metalog fits determined by (term_limit-term_lower_bound)+1\n                            )\n                * pdf_1, pdf_2, ... , pdf_n are the metalog pdfs returned by pdf_quantile_builder.pdfMetalog method\n                * cdf_1, cdf_2, ... , cdf_n are the metalog quantiles returned by pdf_quantile_builder.quantileMetalog method\n            \n            - m_dict['y']: (:obj: `numpy.ndarray` of type float):\n                * Array of bin widths for both the pdf_n and cdf_n\n\n            - m_dict['Validation']: (:obj:`pandas.DataFrame` with columns ['term', 'valid', 'method'] of type str):\n                * 'term': each metalog estimation given a number of terms\n                * 'valid': boolean flag indicating if the metalog estimation was valid or not\n                * 'method': a string indicating which method was used for the metalog estimation\n\n    "
    A = pd.DataFrame()
    c_a_names = []
    c_m_names = []
    Mh = pd.DataFrame()
    Validation = pd.DataFrame()
    df_MH_temp_list = list()
    df_A_temp_list = list()
    df_Validation_temp_list = list()
    for i in range(term_lower_bound, (term_limit + 1)):
        Y = m_dict['Y'].iloc[:, 0:i]
        eye = np.eye(Y.shape[1])
        z = m_dict['dataValues']['z']
        y = m_dict['dataValues']['probs']
        step_len = m_dict['params']['step_len']
        methodFit = 'OLS'
        a_name = ('a' + str(i))
        m_name = ('m' + str(i))
        M_name = ('M' + str(i))
        c_m_names = np.append(c_m_names, [m_name, M_name])
        c_a_names = np.append(c_a_names, a_name)
        if ((fit_method == 'any') or (fit_method == 'MLE')):
            try:
                temp = np.dot(np.dot(np.linalg.inv((np.dot(Y.T, Y) + (alpha * eye))), Y.T), z)
            except:
                temp = a_vector_LP(m_dict, term_limit=i, term_lower_bound=i, diff_error=diff_error, diff_step=diff_step)
                methodFit = 'Linear Program'
        if (fit_method == 'OLS'):
            try:
                temp = np.dot(np.dot(np.linalg.inv((np.dot(Y.T, Y) + (alpha * eye))), Y.T), z)
            except:
                raise RuntimeError('OLS was unable to solve infeasible or poorly formulated problem')
        if (fit_method == 'LP'):
            temp = a_vector_LP(m_dict, term_limit=i, term_lower_bound=i, diff_error=diff_error, diff_step=diff_step)
            methodFit = 'Linear Program'
        if (fit_method == 'MLE'):
            temp = a_vector_MLE(temp, y, i, m_dict, bounds, boundedness)
        temp = np.append(temp, np.zeros((term_limit - i)))
        if (len(z) < 100):
            y2 = np.linspace(step_len, (1 - step_len), int(((1 - step_len) / step_len)))
            tailstep = (step_len / 10)
            y1 = np.linspace(tailstep, (min(y2) - tailstep), int(((min(y2) - tailstep) / tailstep)))
            y3 = np.linspace((max(y2) + tailstep), (max(y2) + (tailstep * 9)), int(((tailstep * 9) / tailstep)))
            y = np.hstack((y1, y2, y3))
        temp_dict = pdf_quantile_builder(temp, y=y, term_limit=i, bounds=bounds, boundedness=boundedness)
        if ((temp_dict['valid'] == 'no') and (fit_method != 'OLS')):
            temp = a_vector_LP(m_dict, term_limit=i, term_lower_bound=i, diff_error=diff_error, diff_step=diff_step)
            temp = np.append(temp, np.zeros((term_limit - i)))
            methodFit = 'Linear Program'
            temp_dict = pdf_quantile_builder(temp, y=y, term_limit=i, bounds=bounds, boundedness=boundedness)
        df_MH_temp_list.append(pd.DataFrame(temp_dict['m']))
        df_MH_temp_list.append(pd.DataFrame(temp_dict['M']))
        df_A_temp_list.append(pd.DataFrame(temp))
        tempValidation = pd.DataFrame(data={'term': [i], 'valid': [temp_dict['valid']], 'method': [methodFit]})
        df_Validation_temp_list.append(tempValidation)
    Validation = pd.concat(df_Validation_temp_list, axis=0)
    Mh = pd.concat(df_MH_temp_list, axis=1)
    A = pd.concat(df_A_temp_list, axis=1)
    A.columns = c_a_names
    Mh.columns = c_m_names
    m_dict['A'] = A
    m_dict['M'] = Mh
    m_dict['M']['y'] = temp_dict['y']
    m_dict['Validation'] = Validation
    A = np.column_stack((np.repeat(1.0, len(A)), A))
    Est = np.dot(m_dict['Y'], A)
    ncols = A.shape[1]
    Z = np.column_stack((np.array(m_dict['dataValues']['z']), np.repeat(m_dict['dataValues']['z'].values, (ncols - 1)).reshape(len(m_dict['dataValues']['z']), (ncols - 1))))
    m_dict['square_residual_error'] = ((Z - Est) ** 2).sum(axis=1)
    return m_dict