Пример #1
0
    def get_slack(self,
                  stage=None,
                  ins=None,
                  max_vectorial=None,
                  ftol=None,
                  lsb_scale=1):
        stage = copy.deepcopy(default(stage, self._start))
        ins = self.default_ins(stage, ins)

        def system(x, scalar):
            return self.system(x,
                               scalar,
                               use_bands=True,
                               sum_conf=True,
                               lsb_scale=lsb_scale)

        system = self.limit_system(system, max_vectorial)

        tol = default(ftol, 1e-12)
        x_scale = 1e-3

        x = self.map_in(stage, ins)
        xap, xan, xbp, xbn, xc = find_ab(system, x, x_scale, tol)

        resp = [
            self.map_out(xap[ii:ii + 1, :])[0] for ii in range(np.size(xap, 0))
        ]
        resn = [
            self.map_out(xan[ii:ii + 1, :])[0] for ii in range(np.size(xan, 0))
        ]
        return list(zip(resp, resn))
Пример #2
0
    def save(self, path_context=None, data_location_override=None, memo=None):
        data_location = default(data_location_override, self.data_location)

        if data_location is None:
            result = self._to_json_dict()

        else:
            computed_path = data_location.computed_path
            save = memo is None or computed_path not in memo

            if save:
                if data_location.extension == "json":
                    with open(computed_path, 'w') as f:
                        json.dump(self._to_json_dict(), f)

                else:
                    np.save(data_location.computed_path, self)

                if memo is not None:
                    memo[computed_path] = self

            result = os.path.normpath(
                os.path.relpath(data_location.computed_path,
                                path_context.computed_directory))

        return result
Пример #3
0
    def refine(self,
               start_stage=None,
               start_ins=None,
               n_iter=None,
               max_vectorial=None,
               lsb_scale=1):
        stage = copy.deepcopy(default(start_stage, self._start))
        ins = self.default_ins(stage, start_ins)

        cm = stage.common_mode
        eff = stage.eff
        caps = stage.caps

        caps_off = np.size(cm) + np.size(eff)
        refs_off = caps_off + np.size(caps)

        norm_range = (
            caps_off,
            refs_off,
        )

        x = self.map_in(stage, ins)

        def system(x, scalar):
            return self.system(x,
                               scalar,
                               use_bands=True,
                               sum_conf=True,
                               lsb_scale=lsb_scale)

        system = self.limit_system(system, max_vectorial)

        x = refine(system, x, norm_range=norm_range, n_iter=n_iter)
        stage, ins = self.map_out([x])
        return stage, ins
Пример #4
0
    def __init__(self,
                 data,
                 x=None,
                 axes_labels=None,
                 style=None,
                 title=None,
                 subplot=(
                     1,
                     1,
                     1,
                 ),
                 plot_kwargs=None,
                 **kwargs):
        super().__init__(**kwargs)
        if style is None:
            style = "plot"

        assert style in self.VALID_STYLES, "Invalid style recieved ({}).".format(
            style)

        self.plot_kwargs = default(plot_kwargs, {})
        self.data = data
        self.x = x
        self.axes_labels = axes_labels
        self.title = title
        self.subplot = subplot
        self.style = style
Пример #5
0
    def recreate_cache(eff,
                       caps,
                       refs,
                       thres,
                       ins,
                       common_mode,
                       c_seq,
                       codes,
                       scalar=None):
        fun = sims.Simulator

        scalar = default(scalar, len(np.shape(eff)) == 0)
        if scalar:
            codes = codes[:, np.newaxis, ...]

        data = fun.simulate_setup(eff,
                                  caps,
                                  refs,
                                  thres,
                                  ins,
                                  common_mode,
                                  c_seq,
                                  scalar=scalar)

        ext_dct = get(data, "extended")[0]
        eff, thres, cm = get(ext_dct, "eff", "thres", "cm")

        # shape (..., n_conf, n_diff,)
        seq_idx = fun.init_seq_idx(c_seq, data)
        set_data = None
        du_idx = None
        trans_idx = None

        sets_cache = []
        cache = {"data": data, "seq_idx": seq_idx, "sets": sets_cache}

        for ii_set, c_set in enumerate(c_seq.configuration_sets):
            set_data = fun.init_set(c_set, data, set_data, du_idx)

            if set_data["previous"] is not None:
                ds_offset = data["ds_offset"]
                code = codes[ds_offset:ds_offset + 1, ...]
                trans_idx = fun.transition_step_idx(c_set, set_data, data,
                                                    code)

            ds_offset = data["ds_offset"]
            code = codes[ds_offset:ds_offset + c_set.ds_samples, ...]
            du_idx = fun.du_indexes(code, c_set, set_data, data)
            sets_cache.append((
                set_data,
                trans_idx,
                du_idx,
            ))

        return cache
Пример #6
0
 def apply_save_pattern(self, pattern, path_context=None):
     path_context = default(path_context, PathContext.relative())
     for ii, item in enumerate(self):
         path = pattern.format(ii)
         data_location = DataLocation.Parse(path,
                                            path_context,
                                            None_on_fail=False)
         if isinstance(item, IterableOfBase):
             item.set_children_data_location(data_location)
         else:
             item.data_location = data_location
Пример #7
0
    def save(self, path_context=None, data_location_override=None, memo=None):
        data_location = default(data_location_override, self.data_location)
        contents = self.contents
        result = {"data": contents}

        if data_location is not None:
            with open(data_location.computed_path, 'w') as f:
                f.write(contents)

            result = os.path.normpath(
                os.path.relpath(data_location.computed_path,
                                path_context.computed_directory))

        return result
Пример #8
0
def refine(system, x, norm_range=None, n_iter=None, xtol=1e-8, ftol=None):
    tol_fact = 1.0
    tol = ftol

    x_len = len(x)
    n_iter = default(n_iter, x_len * x_len)

    prev_x = x
    x_scale = 1e-1

    norm = np.linalg.norm

    if ftol is None:
        tol = system(x, scalar=True).item() * tol_fact

    for ii in range(n_iter):
        print("-" * 30)
        print("Iter {}, tol: {}".format(ii, tol))
        print("-" * 30)

        xap, xan, xbp, xbn, xc = find_ab(system, x, x_scale, tol)
        prev_x = x
        x = compute_movement(system, xap, xan, xbp, xbn, xc, tol)

        print(x_scale)
        print(x - prev_x)

        if REBUNDANT_CHECKS:
            assert system(x, scalar=True).item() - tol <= 0

        if norm_range is not None:
            slc = slice(norm_range[0], norm_range[1])
            x[slc] /= np.sum(x[slc])

        if REBUNDANT_CHECKS:
            assert system(x, scalar=True).item() - tol <= 0

        x_scale = 0.5 * (norm(xbp - x[np.newaxis, ...], axis=1) +
                         norm(xbn - x[np.newaxis, ...], axis=1))
        print("Tol before: {}".format(tol))
        tol = min(tol, system(x, scalar=True).item() * tol_fact)
        print("Tol after : {}".format(tol))

        if np.linalg.norm(x - prev_x) < xtol:
            print("xtol reached")
            break

    return x
Пример #9
0
    def Parse(cls, path, path_context=None, None_on_fail=True):
        path_context = default(path_context, PathContext.relative())
        if isinstance(path, str):
            directory, name_ext = os.path.split(path)
            dot_idx = name_ext.rfind('.')

            if dot_idx >= 0:
                name = name_ext[:dot_idx]
                ext = name_ext[dot_idx + 1:]

            else:
                name = name_ext
                ext = None

            return cls(path_context, directory, name, ext)

        else:
            if None_on_fail:
                return None
            else:
                raise ValueError("path is not a string.")
Пример #10
0
def run(args):
    n_bits = args.nbits
    n_refs = default(args.nrefs, 3)

    seed = None if args.seed is None else int(args.seed)

    meta = gen.StageMeta(args.nbits,
                         n_refs,
                         eff=args.eff,
                         cap=args.cap,
                         common_mode=args.common_mode,
                         fsr=(
                             args.min,
                             args.max,
                         ),
                         differential=args.differential,
                         seed=seed)

    data_location = data.DataLocation(data.PathContext.relative(),
                                      args.location, args.dest, "json")
    print(" saving {}...".format(data_location.computed_path))
    data.save(meta, data_location)
Пример #11
0
    def save(self, path_context=None, data_location_override=None, memo=None):
        data_location = default(data_location_override, self.data_location)
        if data_location is None:
            result = self._to_json_dict(path_context, memo=memo)

        else:
            computed_path = data_location.computed_path
            save = memo is None or computed_path not in memo

            local_path_context = data_location.as_path_context()
            if save:
                with open(computed_path, 'w') as f:
                    dct = self._to_json_dict(local_path_context, memo=memo)
                    json.dump(dct, f, indent=2)

                if memo is not None:
                    memo[computed_path] = self

            result = os.path.normpath(
                os.path.relpath(data_location.computed_path,
                                path_context.computed_directory))

        return result
Пример #12
0
    def __init__(self,
                 start_stage,
                 configuration_sequence,
                 codes,
                 mask=None,
                 sum_conf=False,
                 use_bands=False):
        assert isinstance(
            configuration_sequence,
            gen.ConfigurationSequence), "Check scalar testbench is being used."
        assert isinstance(
            start_stage,
            gen.StageParameters), "Check scalar testbench is being used."

        self._start = start_stage
        self._codes = codes
        self._configuration_sequence = configuration_sequence

        self._mask = default(mask, {})
        assert all(key in self.MASK_KEYS for key in self._mask.keys())

        self.sum_conf = sum_conf
        self.use_bands = use_bands
Пример #13
0
def snr(adc_real, adc_assumed=None, sampling_factor=16):
    """
    Computes the signal to noise ratio (SNR) of an ADC. The output is in
    absolute magnitude (not decibels or bits).

    :param adc_real: Adc to be simulated
    :type n_caps: :class:`gen.PipeParameters`
    :param adc_assumed: Parameters used to calibrate the conversion, None to
        assume perfect knowledge.
    :type adc_assumed: :class:`gen.PipeParameters`
    :param sampling_factor: The number of samples used to calculate the SNR is
        `(2**adc_n_bits + 1) * sampling_factor`, more samples increases
        precision.
    :type sampling_factor: :class:`int`
    :returns: The signal to noise ratio of the adc assuming its parameters, in
        absoulte magnitude.
    :rtype: :class:`float`
    """
    adc_assumed = default(adc_assumed, adc_real)

    assert all(real.meta == assumed.meta for real, assumed in
        zip(adc_real.stages, adc_assumed.stages))
    assert len(adc_real.stages) == len(adc_assumed.stages)
    assert np.size(adc_real.tail) == np.size(adc_assumed.tail)

    tot_bits = ( sum([stage.meta.n_bits for stage in adc_real.stages])
                + int(np.log2(np.size(adc_real.tail))) )
    samples = int((2**tot_bits + 1) * sampling_factor)
    original_signal = np.linspace(*adc_real.stages[0].meta.fsr, samples)

    conversion, tail_code = adc_real.convert(original_signal[..., np.newaxis])
    converted_signal = adc_assumed.rebuild(conversion, tail_code)

    signal_power = np.power(original_signal - np.mean(original_signal), 2)
    error_power = np.power(original_signal - converted_signal, 2)

    return np.sum(signal_power) / np.sum(error_power)
Пример #14
0
 def __deepcopy__(self, memo=None):
     memo = default(memo, {})
     return JsonIterable(
         tuple(copy.deepcopy(ee, memo=memo) for ee in self))
Пример #15
0
    def simulate(self,
                 eff,
                 caps,
                 refs,
                 thres,
                 ins,
                 common_mode,
                 c_seq,
                 scalar=None,
                 raise_=False):
        scalar = default(scalar, len(np.shape(eff)) == 0)

        meta = c_seq.meta

        data = self.simulate_setup(eff,
                                   caps,
                                   refs,
                                   thres,
                                   ins,
                                   common_mode,
                                   c_seq,
                                   scalar=scalar)

        self._standard_deviations(meta, data)

        idx_dct, ext_dct, n_dct = get(data, "indexing", "extended", "n")

        eff, thres, cm = get(ext_dct, "eff", "thres", "cm")
        n_diff = get(n_dct, "n_diff")[0]

        u_history = []

        with self._random_state as _:
            # shape (..., n_conf, n_diff,)
            seq_idx = self.init_seq_idx(c_seq, data)
            u = self.init_seq(seq_idx, data)

            if self.u_history:
                u_history.append(u)

            # Simulate each configuration set
            codes = []

            du_idx = None
            set_data = None
            n_sets = len(c_seq.configuration_sets)

            for ii_set, c_set in enumerate(c_seq.configuration_sets):
                set_data = self.init_set(c_set, data, set_data, du_idx)

                if set_data["previous"] is not None:
                    code = self.u_thres_to_code(u[-1, ...], thres, data)
                    code = code[np.newaxis, ...]

                    trans_idx = self.transition_step_idx(
                        c_set, set_data, data, code)
                    u = self.transition_step(trans_idx, u[-1:, ...], set_data,
                                             data)

                    codes.append(code)

                    if self.u_history:
                        u_history.append(u)

                for sample in range(c_set.ds_samples):
                    # print(" {}/{} Sample {}/{} ({:0.2f}%)".format(
                    #     ii_set+1, n_sets, sample+1, c_set.ds_samples, 100*sample/c_set.ds_samples),
                    #     end='\r')
                    code = self.u_thres_to_code(u[-1, ...], thres, data)
                    code = code[np.newaxis, ...]
                    codes.append(code)

                    du_idx = self.du_indexes(code, c_set, set_data, data)
                    # used in u
                    du = self.du_compute(du_idx, c_set, set_data, data)
                    u = ne.evaluate("u*eff + (1-eff)*cm + du")

                    # common mode feedback
                    if n_diff == 2:
                        u += cm[np.newaxis, ...] - np.mean(
                            u, axis=-1, keepdims=True)

                    if self.u_history:
                        u_history.append(u)

            codes = np.concatenate(codes, axis=0)

            if self.u_history:
                u_history = np.concatenate(u_history, axis=0)

            if scalar:
                assert np.size(codes, 1) == 1
                assert np.size(u_history, 1) == 1

                codes = codes[:, 0, ...]
                u_history = u_history[:, 0, ...]

            if ((u_history < meta.fsr[0] - meta.lsb).any()
                    or (u_history > meta.fsr[1] + meta.lsb).any()):

                message = "Residual out of range."

                if raise_:
                    raise ValueError(message)
                else:
                    warnings.warn(message)

            return codes, u_history
Пример #16
0
def load(data_class, data_location, memo=None):
    memo = default(memo, {})
    return data_class.Load(data_location.path_context, data_location.filepath,
                           memo)
Пример #17
0
def save(data, data_location_override=None, memo=None):
    memo = default(memo, {})
    path_context = PathContext.relative()
    return data.save(path_context, data_location_override, memo=memo)
Пример #18
0
    def __init__(self,
                 stages,
                 ins,
                 configuration_sequence,
                 shape=None,
                 data_location=None):
        super().__init__(data_location)

        NestedStages = data.nested_lists_of(gen.StageParameters)
        NestedSequences = data.nested_lists_of(gen.ConfigurationSequence)

        if not isinstance(configuration_sequence, NestedSequences):
            conf_shape = np.shape(configuration_sequence)
            configuration_sequence = NestedSequences(configuration_sequence,
                                                     len(conf_shape))

        conf_shape = np.shape(configuration_sequence.data)

        if not isinstance(stages, NestedStages):
            shape = default(shape, np.shape(stages))
            dims = len(shape)
            cur = stages
            root_arr = stages

            # Check a valid 0,0,0...
            for dd in range(dims):
                assert isinstance(cur, (
                    tuple,
                    list,
                ))
                cur = cur[0]

            # Check elements
            for idx in cartesian(*tuple(range(ss) for ss in shape)):
                assert isinstance(misc.getitem(stages, idx),
                                  gen.StageParameters)

            # Check regularity
            def rec_check(lst, shape):
                valid = (not isinstance(lst, list)
                         and len(shape) == 0) or len(lst) == shape[0]
                if len(shape) > 1:
                    sub_shape = shape[1:]
                    valid = valid and all(
                        [rec_check(llst, sub_shape) for llst in lst])
                return valid

            assert rec_check(stages, shape)

        else:
            stages_shape = np.shape(stages.data)
            shape = default(shape, stages_shape)

            assert shape == stages_shape

            dims = len(shape)
            root_arr = stages.data

        ref_element = misc.getitem(root_arr, (0, ) * dims)
        ins = data.at_least_ndarray(ins)
        if len(np.shape(ins)) == 1:
            ins = ins[..., np.newaxis]

        # Broadcast ins
        if len(np.shape(ins)) == 2:
            ins = ins[(np.newaxis, ) * dims + (Ellipsis, )]
            ins = np.tile(ins, shape + (
                1,
                1,
            ))

        assert len(np.shape(ins)) == dims + 2

        if np.size(ins, -1) != ref_element.meta.n_diff:
            cm = ref_element.meta.common_mode
            ins = np.concatenate((
                cm - ins,
                cm + ins,
            ), axis=1)

        # All meta the same
        for idx in cartesian(*tuple(range(ss) for ss in shape)):
            c_element = misc.getitem(root_arr, idx)
            assert c_element.meta == ref_element.meta

        self._stages = NestedStages.EnsureIsInstance(stages)
        self._shape = shape
        self._ins = ins
        self._configuration_sequence = configuration_sequence
Пример #19
0
    def system(self,
               x,
               scalar=False,
               use_bands=None,
               sum_conf=None,
               limit_samples=None,
               lsb_scale=1):
        if scalar:
            x = [x]

        cm, eff, caps, refs, thres, ins = self._map_internal(x)
        ext_codes = self._codes[:, np.newaxis, ...]

        if not hasattr(self, "_cache"):
            self._cache = {}

        base_shape = np.shape(x)[:-1]
        if base_shape not in self._cache:
            print("Generating cache for {}".format(base_shape))
            self._cache[base_shape] = self.recreate_cache(
                eff, caps, refs, thres, ins, cm, self._configuration_sequence,
                ext_codes)

        use_bands = default(use_bands, self.use_bands)
        sum_conf = default(sum_conf, self.sum_conf)

        ext_codes = self._codes[:, np.newaxis, ...]

        u = self.recreate(eff,
                          caps,
                          refs,
                          thres,
                          ins,
                          cm,
                          self._configuration_sequence,
                          self._cache[base_shape],
                          limit_samples=limit_samples)

        meta = self._configuration_sequence.meta
        # Ignore last u since it is not converted to code
        u = np.diff(u[:-1, :,
                      ...], axis=-1) if meta.differential else u[:-1, :, ...,
                                                                 -1]
        samples = np.size(u, 0)

        u_center, lsb = self._compute_u_center(thres)
        thres_bits, thres_half = gen.infer_thres_bits(thres[0, ...])
        ideal_lsb = gen.compute_lsb(thres_bits, *self._start.meta.fsr,
                                    thres_half)

        lsb = lsb + ideal_lsb * (lsb_scale - 1) if use_bands else np.zeros((
            samples,
            1,
            1,
        ))
        result = np.maximum(
            np.abs(u - u_center[:samples, ...]) - lsb[:samples, ...] / 2, 0)

        if DEBUG:  # FIXME
            import matplotlib.pyplot as plots
            try:
                print(np.shape(result))
                sum_axis = tuple(range(len(np.shape(result)) - 1))
                cut = (np.sum(result, axis=sum_axis) > 0).tolist().index(True)
                print("Found cut {}".format(cut))

            except:
                cut = 10
                print("Not found cut")

            x_thres = np.stack((
                np.zeros_like(thres[0, :]),
                np.full_like(thres[0, :], samples),
            ),
                               axis=0)
            y_thres = np.stack((thres[0, :], ) * 2, axis=0)
            plots.plot(x_thres, y_thres, c='orange', linestyle='-.')
            plots.plot(u[:, 0, cut, ...], 'r')
            internal, _ = self.configuration_sequence.configuration_sets[
                0].generate_in(self.configuration_sequence.
                               configuration_sets[0].ds_samples)
            internal = np.sum(internal, axis=(
                -2,
                -1,
            ))
            plots.plot(0.25 * (internal[:, cut, ...] - 1.5), 'cyan')
            #plots.plot(internal[:samples, cut, ...], 'k')

            adj_codes = (0.5 /
                         (np.max(self._codes))) * (self._codes -
                                                   np.max(self._codes) / 2)
            plots.plot(adj_codes[:samples, cut, ...], 'k')
            plots.plot(u_center[:samples, 0, cut, ...], 'b')
            plots.plot(u_center[:samples, 0, cut, ...] +
                       lsb[:samples, 0, cut, ...] / 2,
                       'g',
                       linestyle='--')
            plots.plot(u_center[:samples, 0, cut, ...] -
                       lsb[:samples, 0, cut, ...] / 2,
                       'g',
                       linestyle='--')

            plots.show()

        if scalar:
            result = result[:, 0, ...]

        else:
            result = np.transpose(result, (
                1,
                0,
            ) + tuple(range(2, len(np.shape(result)))))

        sum_axis = (
            -2,
            -1,
        ) if sum_conf else (-2, )
        result = np.sum(result, axis=sum_axis)

        if PRINT_ERROR:
            print("System error: {}".format(np.sum(np.power(result, 2))))

        return result
Пример #20
0
def calib(meta, args, interlace, use_full_range=None):
    n_caps = meta.n_caps
    n_refs = meta.n_refs
    n_diff = meta.n_diff

    n_cs = (n_caps - 1) // 2
    n_cf = n_caps - n_cs

    use_full_range = misc.default(use_full_range, n_cs < 2)
    ds_samples = args.samples

    if args.n_test > 0:
        raise ValueError("Minimal does not support test inputs.")

    comb_cs = misc.iterate_combinations(n_caps, n_cs)
    if args.full:
        comb_cs = [tuple(misc.iterate_permutations(cs)) for cs in comb_cs]
        comb_cs = [elem for tlp in comb_cs for elem in tlp]

    slice_ = slice(None) if use_full_range else slice(1, -1)

    comb_refs = gen.ds_map(n_cs, n_refs, n_cs * (n_refs - 1) + 1)
    comb_refs = np.transpose(comb_refs[:, slice_], (
        1,
        0,
        2,
    ))
    comb_refs = comb_refs.tolist()
    comb_refs = [(
        comb_refs[ii],
        comb_refs[jj],
    ) for ii in range(len(comb_refs)) for jj in range(ii + 1, len(comb_refs))]

    comb_cs = list(comb_cs)
    comb_refs = list(comb_refs)

    even_configs = []
    even_ins = []

    ics = []

    with misc.push_random_state():
        seed = None if args.seed is None else int(args.seed)
        np.random.seed(seed)

        for cs_ii, refs_ii in cartesian(comb_cs, comb_refs):
            even_configs.append(gen.Configuration(meta, cs_ii))

            top_ii, bot_ii = refs_ii
            if args.inputs == "":
                sub_seed = np.random.randint(0, 4294967296)
                even_ins.append(
                    gen.InternalRandom(meta, np.size(cs_ii), sub_seed))

            else:
                top = gen.InternalDC(meta, top_ii)
                bot = gen.InternalDC(meta, bot_ii)

                even_ins.append(gen.ACCombinator(meta, top, bot, args.period))

            inv = [[n_refs - 1 - iii for iii in ii] for ii in top_ii]
            inv = inv + [[n_refs // 2, n_refs - n_refs // 2][:n_diff]
                         ] * (n_cf - n_cs)
            ics.append(gen.InitialCondition(meta, inv))

    if interlace:
        n_cs_h = n_cs // 2
        assert n_cs_h > 0, "Not enough capacitors to decrease bits."

        odd_configs = []
        odd_ins = []

        for conf, in_ in zip(even_configs, even_ins):
            left = (n_cs - n_cs_h) // 2
            cs_range = range(left, left + n_cs_h)
            mask = np.zeros((n_cs, ), dtype=bool)
            mask[cs_range] = 1

            odd_configs.append(
                gen.Configuration(conf.meta, conf.cs[cs_range, :]))
            odd_ins.append(gen.InputMask(in_.meta, in_, mask))

    else:
        odd_ins = even_ins
        odd_configs = even_configs

    conf_sets = []
    parity = 0
    for samples in ds_samples:
        if parity == 0:
            configs = even_configs
            inputs = even_ins

        else:
            configs = odd_configs
            inputs = odd_ins

        conf_sets.append(gen.ConfigurationSet(samples, inputs, configs))
        parity = (parity + 1) % 2

    if args.ic == "clear":
        ics = [gen.InitialCondition.Discharged(meta, n_cf)] * len(odd_ins)
    elif args.ic == "precharge":
        pass
    else:
        raise ValueError("ic type {} not supported".format(args.ic))

    return gen.ConfigurationSequence(ics, conf_sets * args.loop)
Пример #21
0
    def recreate(eff,
                 caps,
                 refs,
                 thres,
                 ins,
                 common_mode,
                 c_seq,
                 cache,
                 scalar=None,
                 limit_samples=None):
        fun = sims.Simulator
        scalar = default(scalar, len(np.shape(eff)) == 0)
        limit_samples = default(limit_samples, c_seq.samples) + 1
        samples = 0

        cache = dict(cache)
        cache["data"] = fun.simulate_setup(eff,
                                           caps,
                                           refs,
                                           thres,
                                           ins,
                                           common_mode,
                                           c_seq,
                                           scalar=scalar)
        data = cache["data"]
        seq_idx = cache["seq_idx"]

        u_history = []

        # shape (..., n_conf, n_diff,)
        u = fun.init_seq(seq_idx, data)
        u_history.append(u)
        samples += 1

        # Simulate each configuration set
        dct_idx, dct_ext, dct_n = get(data, "indexing", "extended", "n")

        n_conf, n_diff = get(dct_n, "n_conf", "n_diff")
        eff, cm = get(dct_ext, "eff", "cm")
        base_shape, base_len = get(dct_idx, "base_shape", "base_len")

        c_sets = c_seq.configuration_sets

        def multi_idx_filter(idx_tuple, sub_idx):
            return tuple(ii[sub_idx] if hasattr(ii, "__getitem__") else ii
                         for ii in idx_tuple)

        for ii_set, c_set, data_trans_du in zip(range(len(c_sets)), c_sets,
                                                cache["sets"]):
            set_data, trans_idx, du_idx = data_trans_du

            if set_data["previous"] is not None:
                u = fun.transition_step(trans_idx, u[-1:, ...], set_data, data)
                u_history.append(u)
                samples += 1

            r_du = (1 - eff) * cm
            n_u = np.empty((c_set.ds_samples, ) + base_shape + (
                n_conf,
                n_diff,
            ))

            local_du_idx = dict(du_idx)
            # used in u
            du = fun.du_compute(du_idx, c_set, set_data, data)

            for idx in cartesian(*tuple(range(ss) for ss in base_shape)):
                local_idx = tuple(slice(ii, ii + 1)
                                  for ii in idx) + (Ellipsis, )
                ext_local_idx = (slice(None), ) + local_idx

                local_du_idx["r_ref"] = local_du_idx["r_ref"][ext_local_idx]
                local_du_idx["m_in_ref"] = multi_idx_filter(
                    local_du_idx["m_in_ref"], ext_local_idx)
                local_du_idx["m_in_ins"] = multi_idx_filter(
                    local_du_idx["m_in_ins"], ext_local_idx)

                zi = u[(slice(-1, None), ) + local_idx] * eff[local_idx]
                local_u = lfilter([1], [1, -eff[local_idx].item()],
                                  du[ext_local_idx] +
                                  r_du[(np.newaxis, ) + local_idx],
                                  zi=zi,
                                  axis=0)[0]
                n_u[ext_local_idx] = local_u

            u = n_u
            u_history.append(u)
            samples += np.size(u, 0)

            if samples >= limit_samples:
                break

        u_history = np.concatenate(u_history, axis=0)
        u_history = u_history[:limit_samples, ...]

        if scalar:
            assert np.size(u_history, 1) == 1
            u_history = u_history[:, 0, ...]

        return u_history
Пример #22
0
    def run_calibration(self,
                        start_stage=None,
                        start_ins=None,
                        n_switches=5,
                        switching_nfev=30,
                        samples_step=512,
                        lsb_scale=1):
        stage = copy.deepcopy(default(start_stage, self._start))
        ins = self.default_ins(stage, start_ins)

        x = self.map_in(stage, ins)
        bounds = self.bounds(ins)

        nfev = switching_nfev
        steps = self._configuration_sequence.samples // samples_step
        steps = [ss * samples_step for ss in range(1, steps)] + [None]

        for limit_samples in steps:
            res = Namespace()
            res.cost = 1

            for try_ in range(n_switches):
                if res.cost == 0:
                    break

                print(" No bands, no bounds {}/{}, limit {}".format(
                    try_ + 1, n_switches, limit_samples))
                res = least_squares(
                    lambda x: self.system(x,
                                          scalar=True,
                                          use_bands=False,
                                          limit_samples=limit_samples,
                                          lsb_scale=lsb_scale),
                    x,
                    max_nfev=nfev,
                    verbose=2)  # FIXME: verbose
                x = res.x

                # Clip
                x = [
                    max(min(xx, M), m)
                    for xx, m, M in zip(x, bounds[0], bounds[1])
                ]

                print(" Bands {}/{}, limit {}".format(try_ + 1, n_switches,
                                                      limit_samples))
                res = least_squares(
                    lambda x: self.system(x,
                                          scalar=True,
                                          use_bands=True,
                                          limit_samples=limit_samples,
                                          lsb_scale=lsb_scale),
                    x,
                    bounds=bounds,
                    max_nfev=nfev,
                    verbose=2)  # FIXME: verbose
                #x, max_nfev=nfev, verbose=2) # FIXME: bounds
                x = res.x

        if res.cost != 0:
            print(" Final no bounds")
            res = least_squares(
                lambda x: self.system(x,
                                      scalar=True,
                                      use_bands=True,
                                      limit_samples=limit_samples,
                                      lsb_scale=lsb_scale),
                x,
                verbose=2)  # FIXME: verbose
            x = res.x

            # Clip
            x = [
                max(min(xx, M), m) for xx, m, M in zip(x, bounds[0], bounds[1])
            ]

            print(" Final")
            res = least_squares(
                lambda x: self.system(x,
                                      scalar=True,
                                      use_bands=True,
                                      limit_samples=limit_samples,
                                      lsb_scale=lsb_scale),
                x,
                bounds=bounds,
                verbose=2)  # FIXME: verbose
            x = res.x

        stage, ins = self.map_out([x])
        return stage, ins