def check_convergence(dSysSettings, dEvalData, dSTOPData, bStop):

    # =================================================================
    # Get the user setting for minimum distance evaluation
    [bEvalOn, dMinDEval] = _check_settings(dSysSettings)

    # =================================================================

    # =================================================================
    # If this evaluation was not on, skip this function
    if bEvalOn == 0:
        return (bStop, dSysSettings, dSTOPData)

    # =================================================================

    # =================================================================
    # Check if the convergence evaluation for this function is on.
    if 'bConvCheck' in dMinDEval:
        bConvCheck = dMinDEval['bConvCheck']
    else:
        bConvCheck = 0

    # =================================================================

    # =================================================================
    # If the convergence evaluation is off, skip this function
    if bConvCheck == 0:
        return (bStop, dSysSettings, dSTOPData)

    # =================================================================

    # =================================================================
    # Get the needed data

    # -----------------------------------------------------------------
    # Get the settings for the convergence

    # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    iEval = dSTOPData['EVAL_MIND']             # Index of the minimum
                                               # distance evaluation

    iMinConvMargin = dSTOPData['iMinConvMargin']   # Minimum convergence
                                                   # margin

    # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    iMargin = dMinDEval['iConvMarg']         # Allowed margin

    iLastPatt = dMinDEval['iConvLastPatt']   # Size of the last data which
                                             # is checked for convergence

    # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    dMinDData = dEvalData['dMinDData']      # The dictionary with internal
                                            # data of evaluation functions and
                                            # counters

    vMinDErrConv = dMinDData['vMinDErrConv']  # Vector with convergence of
                                              # average minimum distance error

    vMinDRConv = dMinDData['vMinDRConv']    # Vector with convergence of the
                                            # ratio of patterns which do not
                                            # violate minimum distance
                                            # requirement

    # -----------------------------------------------------------------
    # =================================================================

    # =================================================================
    # Check the convergence

    # Measure the convergence:

    # [average min dist error]
    (bConvOkAE, iConvDistAE) = \
        _data_convergence.is_data_converged(vMinDErrConv, iLastPatt,
                                            iMargin, iMinConvMargin)

    # [ratio of patterns which do not violate minimum distance requirement]
    (bConvOkIP, iConvDistIP) = \
        _data_convergence.is_data_converged(vMinDRConv, iLastPatt,
                                            iMargin, iMinConvMargin)

    bConvOk = bConvOkAE and bConvOkIP
    # bConvOkAE == 0 if there is no convergence
    # bConvOkIP == 0 if there is no convergence

    # Check the stop condition
    (bStop, dSTOPData, inxC, bLocalStop) = \
        _data_convergence.check_conv_counter(dSTOPData, bConvOk,
                                             bStop, iEval)

    # =================================================================

    # =================================================================
    # Report to the console (if needed)

    # Get the verbose settings
    (bInfo, _) = _verbose.get_settings(dSysSettings)

    # Print the info
    if bInfo == 1:

        stdout.write('STOP CHECK: ')
        stdout.write('Minimum distance eval convergence:           ')
        if bConvOkAE == 1:
            stdout.write('[average error]: OK            ')
        else:
            strMessage = '[average error]: FAILED (%2.2f) ' % (iConvDistAE)
            stdout.write(strMessage)

        if bConvOkIP == 1:
            stdout.write('[rat. correct patterns]: OK                ')
        else:
            strMessage = '[rat. correct patterns]: FAILED (%2.2f) ' \
                % (iConvDistIP)
            stdout.write(strMessage)

        if bConvOk == 1:
            strMessage = 'OK %d TIME' % (inxC)
            stdout.write(strMessage)
            if bLocalStop == 1:
                strMessage = ' (enough) \n' % (inxC)
                stdout.write(strMessage)
            else:
                strMessage = '\n'
                stdout.write(strMessage)

        else:
            strMessage = '\n'
            stdout.write(strMessage)

    # =================================================================

    # =================================================================
    return (bStop, dSysSettings, dSTOPData)
def check_convergence(dSysSettings, dEvalData, dSTOPData, bStop):

    # =================================================================
    # Get the user setting for correct patterns counter
    (bCntrOn, dRCPCntr) = _check_settings(dSysSettings)

    # =================================================================

    # =================================================================
    # If this counter was not on, skip this function
    if bCntrOn == 0:
        return (bStop, dSysSettings, dSTOPData)

    # =================================================================

    # =================================================================
    # Check if the convergence check for this function is on.
    if 'bConvCheck' in dRCPCntr:
        bConvCheck = dRCPCntr['bConvCheck']
    else:
        bConvCheck = 0

    # =================================================================

    # =================================================================
    # If the convergence check is off, skip this function
    if bConvCheck == 0:
        return (bStop, dSysSettings, dSTOPData)

    # =================================================================

    # =================================================================
    # Get the needed data

    # -----------------------------------------------------------------
    # Get the settings for the convergence

    # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    iCheck = dSTOPData['EVAL_RCP']    # Index of counter of correct patterns

    iMinConvMargin = dSTOPData['iMinConvMargin']  # Minimum convergence
                                                  # margin

    # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    iMargin = dRCPCntr['iConvMarg']          # Allowed margin

    iLastPatt = dRCPCntr['iConvLastPatt']    # Size of the last data which
                                             # is checked for convergence

    # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    dRCPData = dEvalData['dRCPData']     # The dictionary with internal data
                                         # of evaluation functions and counter

    vCorrConv = dRCPData['vCorrConv']    # Get the vector with convergence of
                                         # the ratio of correct patterns

    # -----------------------------------------------------------------
    # =================================================================

    # =================================================================
    # Check the convergence

    # Measure the convergence:
    # Vector with convergence of the ratio of correct patterns
    (bConvOk, iConvDist) = \
        _data_convergence.is_data_converged(vCorrConv, iLastPatt,
                                            iMargin, iMinConvMargin)

    # Check the stop condition
    [bStop, dSTOPData, inxC, bLocalStop] = \
        _data_convergence.check_conv_counter(dSTOPData, bConvOk,
                                             bStop, iCheck)

    # =================================================================

    # =================================================================
    # Report to the console (if needed)

    # Get the verbose settings
    (bInfo, _) = _verbose.get_settings(dSysSettings)

    # Print the info
    if bInfo == 1:

        stdout.write('STOP CHECK: ')
        stdout.write('Correct patterns counter convergence:        ')
        if bConvOk == 1:
            stdout.write('[ratio]: OK             ')
            stdout.write('                                            ')
        else:
            strMessage = '[ratio]: FAILED (%2.2f) ' % (iConvDist)
            stdout.write(strMessage)

        if bConvOk == 1:
            strMessage = 'OK %d TIME' % (inxC)
            stdout.write(strMessage)
            if bLocalStop == 1:
                strMessage = ' (enough) \n' % (inxC)
                stdout.write(strMessage)
            else:
                strMessage = '\n'
                stdout.write(strMessage)
        else:
            strMessage = '\n'
            stdout.write(strMessage)

    # =================================================================

    # =================================================================
    return (bStop, dSysSettings, dSTOPData)
def check_convergence(dSysSettings, dEvalData, dSTOPData, bStop):

    # =================================================================
    # Get the user setting for PDF evaluation
    (bEvalOn, dPDFTotEval) = _check_settings(0, dSysSettings, 0)
    # =================================================================

    # =================================================================
    # If this evaluation was not on, skip this function
    if bEvalOn == 0:
        return (bStop, dSysSettings, dSTOPData)

    # =================================================================

    # =================================================================
    # Check if the convergence check for this function is on.
    if 'bConvCheck' in dPDFTotEval:
        bConvCheck = dPDFTotEval['bConvCheck']
    else:
        bConvCheck = 0
    # =================================================================

    # =================================================================
    # If the convergence check is off, skip this function
    if bConvCheck == 0:
        return (bStop, dSysSettings, dSTOPData)

    # =================================================================

    # =================================================================
    # Get the needed data

    # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    iEval = dSTOPData['EVAL_PDF']                   # Index of the PDF
                                                    # evaluation

    iMinConvMargin = dSTOPData['iMinConvMargin']    # Minimum convergence
                                                    # margin

    # -----------------------------------------------------------------
    # Get the settings for the convergence

    iMargin = dPDFTotEval['iConvMarg']            # Allowed margin

    iLastPatt = dPDFTotEval['iConvLastPatt']      # Size of the last data
                                                  # which is checked for
                                                  # convergence

    # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    dPDFTotData = dEvalData['dPDFTotData']        # The dictionary with
                                                  # internal data of
                                                  # of PDF evaluation  (for
                                                  # all patterns)

    vPDFErrTotConv = dPDFTotData['vPDFErrTotConv']   # Vector with convergence
                                                     # of PDF error

    # -----------------------------------------------------------------
    # =================================================================

    # =================================================================

    # -----------------------------------------------------------------

    # Measure the convergence
    (bConvOk, iConvDist) = \
        _data_convergence.is_data_converged(vPDFErrTotConv, iLastPatt,
                                            iMargin, iMinConvMargin)

    # Check the stop condition
    (bStop, dSTOPData, inxC, bLocalStop) = \
        _data_convergence.check_conv_counter(dSTOPData, bConvOk,
                                             bStop, iEval)

    # =================================================================

    # =================================================================
    # Report to the console (if needed)

    # Get the verbose settings
    (bInfo, _) = _verbose.get_settings(dSysSettings)

    # Print the info
    if bInfo == 1:
        stdout.write('STOP CHECK: ')
        stdout.write('PDF eval convergence:                        ')

        if bConvOk == 1:
            stdout.write('[error]: OK              ')
            stdout.write('                                           ')
        else:
            strMessage = '[error]: FAILED (%2.2f) ' % (iConvDist)
            stdout.write(strMessage)

        if bConvOk == 1:
            strMessage = 'OK %d TIME' % (inxC)
            stdout.write(strMessage)
            if bLocalStop == 1:
                strMessage = ' (enough) \n' % (inxC)
                stdout.write(strMessage)
            else:
                strMessage = '\n'
                stdout.write(strMessage)

        else:
            strMessage = '\n'
            stdout.write(strMessage)

    # =================================================================

    # =================================================================
    return (bStop, dSysSettings, dSTOPData)