Пример #1
0
    def set_selective_phsann_settings(self, min_period, max_period):
        '''
        Phase anneal some phases only.

        Phases having periods less than min_period and greater than max period
        are left untouched.

        Parameters:
        ----------
        min_period : int or None
            Phases having periods less than min_period are not
            annealed/randomized. Should be greater than zero and less than
            max_period. An error is raised if min_period does not exist in the
            data.
        max_period : int or None
            Phases having periods greater than max_period are not
            annealed/randomized. Should be greater than zero and greater than
            min_period. An error is raised if max_period does not exist in the
            data.
        '''

        if self._vb:
            print_sl()

            print('Setting selective phases for phase annealing...\n')

        if isinstance(min_period, int):
            assert min_period > 0, 'Invalid min_period!'

        elif min_period is None:
            pass

        else:
            raise AssertionError('min_period can only be None or an int!')

        if isinstance(max_period, int):
            assert max_period > 0, 'Invalid max_period!'

        elif max_period is None:
            pass

        else:
            raise AssertionError('max_period can only be None or an int!')

        if isinstance(min_period, int) and isinstance(max_period, int):
            assert max_period > min_period, (
                'max_period must be greater than min_period!')

        self._sett_sel_phs_min_prd = min_period
        self._sett_sel_phs_max_prd = max_period

        if self._vb:
            print('Minimum period:', self._sett_sel_phs_min_prd)
            print('Maximum period:', self._sett_sel_phs_max_prd)

            print_el()

        self._sett_sel_phs_set_flag = True
        return
Пример #2
0
    def plot(self):

        if self._vb:
            print_sl()

            print('Plotting...')

        assert self._plt_verify_flag, 'Plot in an unverified state!'

        ftns_args = []

        self._fill_osv_args_gnrc(ftns_args)

        # Variables specific to PA.
        if self._plt_osv_flag:
            ftns_args.extend([
                (self._plot_phs_red_rates, []),
                (self._plot_phs_idxs_sclrs, []),
                ])

        self._fill_ss_args_gnrc(ftns_args)

        self._fill_ms_args_gnrc(ftns_args)

        self._fill_qq_args_gnrc(ftns_args)

        assert ftns_args

        n_cpus = min(self._n_cpus, len(ftns_args))

        if n_cpus == 1:
            for ftn_arg in ftns_args:
                self._exec(ftn_arg)

        else:
            mp_pool = Pool(n_cpus)

            # NOTE:
            # imap_unordered does not show exceptions, map does.

            # mp_pool.imap_unordered(self._exec, ftns_args)

            mp_pool.map(self._exec, ftns_args, chunksize=1)

            mp_pool.close()
            mp_pool.join()

            mp_pool = None

        if self._vb:
            print('Done plotting.')

            print_el()

        return
Пример #3
0
    def _show_rltzn_situ(
            self,
            iter_ctr,
            rltzn_iter,
            iters_wo_acpt,
            tol,
            temp,
            phs_red_rate,
            acpt_rate,
            new_obj_val,
            obj_val_min,
            iter_wo_min_updt):

        c1 = self._sett_ann_max_iters >= 10000
        c2 = not (iter_ctr % (0.05 * self._sett_ann_max_iters))

        if (c1 and c2) or (iter_ctr == 1):
            with self._lock:
                print_sl()

                print(
                    f'Realization {rltzn_iter} finished {iter_ctr} out of '
                    f'{self._sett_ann_max_iters} iterations on {asctime()}.')

                print(f'Current objective function value: {new_obj_val:9.2E}')

                print(
                    f'Running minimum objective function value: '
                    f'{obj_val_min:9.2E}\n')

                iter_wo_min_updt_ratio = (
                    iter_wo_min_updt / self._sett_ann_max_iter_wo_min_updt)

                print(
                    f'Stopping criteria variables:\n'
                    f'{self._alg_cnsts_stp_crit_labs[0]}: '
                    f'{iter_ctr/self._sett_ann_max_iters:6.2%}\n'
                    f'{self._alg_cnsts_stp_crit_labs[1]}: '
                    f'{iters_wo_acpt/self._sett_ann_max_iter_wo_chng:6.2%}\n'
                    f'{self._alg_cnsts_stp_crit_labs[2]}: {tol:9.2E}\n'
                    f'{self._alg_cnsts_stp_crit_labs[3]}: {temp:9.2E}\n'
                    f'{self._alg_cnsts_stp_crit_labs[4]}: '
                    f'{phs_red_rate:6.3%}\n'
                    f'{self._alg_cnsts_stp_crit_labs[5]}: {acpt_rate:6.3%}\n'
                    f'{self._alg_cnsts_stp_crit_labs[6]}: '
                    f'{iter_wo_min_updt_ratio:6.2%}')

                print_el()
        return
Пример #4
0
    def set_pa_sa_settings(self, phase_reduction_rate_type,
                           mag_spec_index_sample_flag, phase_reduction_rate,
                           min_phs_red_rate):
        '''
        Addtional variables used during annealing realted to phase annealing.

        Parameters
        ----------
        phase_reduction_rate_type : integer
            How to limit the magnitude of the newly generated phases.
            A number between 0 and 3.
            0:    No limiting performed.
            1:    A linear reduction with respect to the maximum iterations is
                  applied. The more the iteration number the less the change.
            2:    Reduce the rate by multiplying the previous rate by
                  phase_reduction_rate.
            3:    Reduction rate is equal to the mean acceptance rate of
                  previous acceptance_rate_iterations.
        mag_spec_index_sample_flag : bool
            Whether to sample new freqeuncy indices on a magnitude spectrum
            CDF based weighting i.e. frequencies having more amplitude
            have a bigger chance of being sampled.
        phase_reduction_rate : float
            If phase_reduction_rate_type is 2, then the new phase reduction
            rate is previous multiplied by phase_reduction_rate_type. Should
            be > 0 and <= 1.
        min_phs_red_rate : float
            The minimum phase reduction rate, below which the change is
            considered as zero. Must be greater than or equal to zero
            and less than one.
        '''

        if self._vb:
            print_sl()

            print('Setting additonal phase annealing parameters...\n')

        assert isinstance(phase_reduction_rate_type,
                          int), ('phase_reduction_rate_type not an integer!')

        assert 0 <= phase_reduction_rate_type <= 3, (
            'Invalid phase_reduction_rate_type!')

        assert isinstance(mag_spec_index_sample_flag,
                          bool), ('mag_spec_index_sample_flag not a boolean!')

        if phase_reduction_rate_type == 2:

            assert isinstance(phase_reduction_rate,
                              float), ('phase_reduction_rate is not a float!')

            assert 0 < phase_reduction_rate <= 1, (
                'Invalid phase_reduction_rate!')

        elif phase_reduction_rate_type in (0, 1, 3):
            pass

        else:
            raise NotImplementedError('Unknown phase_reduction_rate_type!')

        assert isinstance(min_phs_red_rate,
                          float), ('min_phs_red_rate not a float!')

        assert 0 <= min_phs_red_rate < 1.0, ('Invalid min_phs_red_rate!')

        self._sett_ann_phs_red_rate_type = phase_reduction_rate_type

        self._sett_ann_mag_spec_cdf_idxs_flag = mag_spec_index_sample_flag

        if phase_reduction_rate_type == 2:
            self._sett_ann_phs_red_rate = phase_reduction_rate

        elif phase_reduction_rate_type in (0, 1, 3):
            pass

        else:
            raise NotImplementedError('Unknown phase_reduction_rate_type!')

        self._sett_ann_min_phs_red_rate = min_phs_red_rate

        if self._vb:

            print('Phase reduction rate type:',
                  self._sett_ann_phs_red_rate_type)

            print('Magnitude spectrum based indexing flag:',
                  self._sett_ann_mag_spec_cdf_idxs_flag)

            print('Phase reduction rate:', self._sett_ann_phs_red_rate)

            print('Minimum phase reduction rate:',
                  self._sett_ann_min_phs_red_rate)

            print_el()

        self._sett_ann_pa_sa_sett_flag = True
        return
Пример #5
0
    def set_limited_phase_randomization_settings(self, obj_val_lower_bound,
                                                 obj_val_upper_bound,
                                                 perturbation_lower_bound,
                                                 perturbation_upper_bound,
                                                 n_perturbation_intervals,
                                                 iterations_per_attempt):
        '''
        Limit the amount of randomization applied to phases such that
        the resulting objective function values stay in given bounds.
        The idea being that with full spectrum phase randomization,
        the resulting objective value becomes so large that it cannot be
        brought down in doable time period.

        This is done by perturbing all phases (excluding the phases
        that were set in set_mult_phase_settings) till the mean
        objective function value falls within given bounds by having smaller
        increments.

        Parameters
        ----------
        obj_val_lower_bound : float
            Lower bound of the objective function. Should be greater than
            zero and less than obj_val_upper_bound. After attempted limited
            phase randomization, the search stops if the mean objective
            value is between obj_val_lower_bound and obj_val_upper_bound.
        obj_val_upper_bound : float
            Upper bound of the objective function. Should be greater than
            obj_val_lower_bound and less than infinity!
        perturbation_lower_bound : float
            How much perturbation ratio to apply at the beginning. For
            example a generated phase is 0.25 Pi and perturbation_lower_bound
            is 0.01 than the resulting phase is shifted by 0.0025 Pi.
            Should be greater than zero.
        perturbation_upper_bound : float
            Upper bound of the perturbation to apply. Should be greater than
            perturbation_lower_bound and less than or equal to 1.0.
        n_perturbation_intervals : int
            The number of values to use in between perturbation_lower_bound
            and perturbation_upper_bound while finding the optimum amount
            of perturbation. Numpy linspace is used for this. Should be
            greater than zero.
        iterations_per_attempt : int
            Number of iterations to take the mean of per perturbation attempt.
            Should be greater than zero.
        '''

        if self._vb:
            print_sl()

            print('Setting limited phase randomization settings...\n')

        assert isinstance(obj_val_lower_bound,
                          float), ('obj_val_lower_bound not a float!')

        assert isinstance(obj_val_upper_bound,
                          float), ('obj_val_upper_bound not a float!')

        assert isinstance(perturbation_lower_bound,
                          float), ('perturbation_lower_bound not a float!')

        assert isinstance(perturbation_upper_bound,
                          float), ('perturbation_upper_bound not a float!')

        assert isinstance(n_perturbation_intervals,
                          int), ('n_perturbation_intervals not an integer!')

        assert isinstance(iterations_per_attempt,
                          int), ('iterations_per_attempt not an integer!')

        assert obj_val_lower_bound > 0, (
            'Invalid value of obj_val_lower_bound!')

        assert obj_val_lower_bound < np.inf, (
            'Invalid value of obj_val_lower_bound!')

        assert obj_val_upper_bound > obj_val_lower_bound, (
            'obj_val_upper_bound not greater than obj_val_lower_bound!')

        assert perturbation_lower_bound > 0, (
            'Invalid value of perturbation_lower_bound!')

        assert perturbation_upper_bound <= 1.0, (
            'Invalid value of perturbation_upper_bound!')

        assert perturbation_upper_bound > perturbation_lower_bound, (
            'perturbation_upper_bound not greater than '
            'perturbation_lower_bound!')

        assert n_perturbation_intervals > 0, (
            'Invalid value of n_perturbation_intervals!')

        assert iterations_per_attempt > 0, (
            'Invalid value of iterations_per_attempt!')

        self._sett_lim_phsrand_obj_lbd = obj_val_lower_bound
        self._sett_lim_phsrand_obj_ubd = obj_val_upper_bound
        self._sett_lim_phsrand_ptrb_lbd = perturbation_lower_bound
        self._sett_lim_phsrand_ptrb_ubd = perturbation_upper_bound
        self._sett_lim_phsrand_n_ptrb_vals = n_perturbation_intervals
        self._sett_lim_phsrand_iters_per_atpt = iterations_per_attempt

        if self._vb:
            print('Objective function lower bound:',
                  self._sett_lim_phsrand_obj_lbd)

            print('Objective function upper bound:',
                  self._sett_lim_phsrand_obj_ubd)

            print('Perturbation lower bound:', self._sett_lim_phsrand_ptrb_lbd)

            print('Perturbation upper bound:', self._sett_lim_phsrand_ptrb_ubd)

            print('Total perturbation intervals:',
                  self._sett_lim_phsrand_n_ptrb_vals)

            print('Iterations per perturbation:',
                  self._sett_lim_phsrand_iters_per_atpt)

            print_el()

        self._sett_lim_phsrand_set_flag = True
        return
Пример #6
0
    def set_initial_phase_spectra_settings(self, initial_phase_spectra_type,
                                           initial_phase_spectra):
        '''
        Specify initial phase spectra to use when phase annealing starts.

        Parameters
        ----------
        initial_phase_spectra_type : int
            The type of phase spectra supplied. 0 refers to a single spectra
            used as the initial one for all realizations. 1 refers to the case
            where each realtization gets a seperate initial spectra.
        initial_phase_spectra : list or tuple of 2D np.float64 np.ndarray
            A container holding the initial spectra. The shape of the
            spectra must correspond to that of the reference data. If N is the
            number of time steps in the reference data and M is the number of
            columns then each spectra should have the shape (N//2 + 1, M).
            The length of initial_phase_spectra should be 1 if
            initial_phase_spectra_type is 0 or equal to the number of
            realizations if initial_phase_spectra_type is 1. All values must
            lie inbetween -pi and +pi.
        '''

        if self._vb:
            print_sl()

            print('Setting initial phase spectra...\n')

        assert isinstance(initial_phase_spectra_type,
                          int), ('initial_phase_spectra_type not an integer!')

        assert initial_phase_spectra_type in (0, 1), (
            'Invalid initial_phase_spectra_type!')

        assert isinstance(
            initial_phase_spectra,
            (tuple, list)), ('initial_phase_spectra not a list or a tuple!')

        assert len(initial_phase_spectra) > 0, ('Empty initial_phase_spectra!')

        for phs_spec in initial_phase_spectra:
            assert isinstance(phs_spec,
                              np.ndarray), ('Phase spectra not a numpy array!')

            assert phs_spec.ndim == 2, 'Phase spectra not 2D!'

            assert phs_spec.dtype == np.float64, (
                'Incorrect data type of phase spectra!')

            assert np.all(
                np.isfinite(phs_spec)), ('Invalid values in phase spectra!')

            assert (np.all(phs_spec >= -np.pi)
                    and np.all(phs_spec <= +np.pi)), (
                        'Values in phase spectra out of range!')

        self._sett_init_phs_spec_type = initial_phase_spectra_type
        self._sett_init_phs_specs = tuple(initial_phase_spectra)

        if self._vb:
            print('Initial phase spectra type:', self._sett_init_phs_spec_type)

            print_el()

        self._sett_init_phs_spec_set_flag = True
        return
Пример #7
0
    def set_mult_phase_settings(self, n_beg_phss, n_end_phss, sample_type,
                                number_reduction_rate):
        '''
        Randomize multiple phases instead of just one.

        A random number of phases are generated for each iteration between
        n_beg_phss and n_end_phss (both inclusive). These values are adjusted
        if available phases/magnitudes are not enough, internally but these
        values are kept.

        Parameters
        ----------
        n_beg_phss : integer
            Minimum phases/magnitudes to randomize per iteration.
            Should be > 0.
        n_end_phss : integer
            Maximum number of phases/magnitudes to randomize per iteration.
            Should be >= n_beg_phss.
        sample_type : integer
            How to sample the number of phases generated for each iteration.
            0:  New phase indices are generated randomly between
                n_beg_phss and n_end_phss, regardless of where in the
                optimization for each iteration.
            1:  The number of newly generated phases depends on the ratio
                of current iteration number and maximum_iterations.
            2:  The number of newly generated phase indices is reduced
                by multiplying with number_reduction_rate at every
                temperature update iteration.
            3:  The number of newly generated phase indices is proportional
                to the acceptance rate.
        number_reduction_rate : float
            Generated phase indices reduction rate. A value between > 0 and
            <= 1. The same as temperature reduction schedule. Required
            to have a valid value only is sample_type == 2.

        NOTE: In case the difference between n_beg_phss and n_end_phss
        is high and mag_spec_index_sample_flag is True and the
        distribution of the magnitude spectrum is highly skewed, it
        will take a while to get the indices (per iteration). So it
        might be a good idea to set mag_spec_index_sample_flag to False.
        '''

        if self._vb:
            print_sl()

            print('Setting multiple phase annealing parameters...\n')

        assert isinstance(n_beg_phss, int), 'n_beg_phss not an integer!'
        assert isinstance(n_end_phss, int), 'n_end_phss not an integer!'
        assert isinstance(sample_type, int), 'sample_type is not an integer!'

        assert n_beg_phss > 0, 'Invalid n_beg_phss!'
        assert n_end_phss >= n_beg_phss, 'Invalid n_end_phss!'

        assert sample_type in (0, 1, 2, 3), 'Invalid sample_type!'

        if sample_type > 0:
            assert n_beg_phss < n_end_phss, (
                'n_beg_phss and n_end_phss cannot be equal for sample_type '
                '> 0!')

        if sample_type == 2:
            assert isinstance(number_reduction_rate,
                              float), ('number_reduction_rate not a float!')

            assert 0 < number_reduction_rate <= 1, (
                'Invalid number_reduction_rate!')

        elif sample_type in (0, 1, 3):
            pass

        else:
            raise NotImplementedError

        self._sett_mult_phs_n_beg_phss = n_beg_phss
        self._sett_mult_phs_n_end_phss = n_end_phss
        self._sett_mult_phs_sample_type = sample_type

        if sample_type == 2:
            self._sett_mult_phss_red_rate = number_reduction_rate

        if self._vb:
            print(f'Starting multiple phase indices: '
                  f'{self._sett_mult_phs_n_beg_phss}')

            print(f'Ending multiple phase indices: '
                  f'{self._sett_mult_phs_n_end_phss}')

            print(f'Multiple phase sampling type: '
                  f'{self._sett_mult_phs_sample_type}')

            print(f'Multiple phase number reduction rate: '
                  f'{self._sett_mult_phss_red_rate}')

            print_el()

        self._sett_mult_phs_flag = True
        return
Пример #8
0
    def _update_wts_phsann(self, phs_red_rate, idxs_sclr):

        if self._sett_wts_lags_nths_set_flag:

            if self._vb:
                print_sl()

                print(f'Computing lag and nths weights...')

            self._set_lag_nth_wts(phs_red_rate, idxs_sclr)

            if self._vb:

                self._show_lag_nth_wts()

                print(f'Done computing lag and nths weights.')

                print_el()

        if self._sett_wts_label_set_flag:

            if self._vb:
                print_sl()

                print(f'Computing label weights...')

            self._set_label_wts(phs_red_rate, idxs_sclr)

            if self._vb:
                self._show_label_wts()

                print(f'Done computing label weights.')

                print_el()

        if self._sett_wts_obj_auto_set_flag:
            if self._vb:
                print_sl()

                print(f'Computing individual objective function weights...')

            self._set_auto_obj_wts(phs_red_rate, idxs_sclr)

            if self._vb:
                self._show_obj_wts()

                print(f'Done computing individual objective function weights.')

                print_el()

        if self._sett_lim_phsrand_set_flag:
            if self._vb:
                print_sl()

                print('Computing limited phase perturbation values...')

            self._cmpt_lim_phsrand_obj_vals(phs_red_rate, idxs_sclr)

            if self._vb:
                print('Done computing limited phase perturbation values.')
                print_el()

        return