Ejemplo n.º 1
0
    def rotate_in_place(a: np.array):
        """  Rotate for N*N array, the result is equivalent to numpy.rot90(a, 3)
        :array: N*N numpy array
        :return: rotated numpy array

        Complexity:
        Time  : O(rc)
        Space : O(rc)
        """

        # 4-way edge swap
        if not a.all():
            raise ArgError()

        row_num, col_num = a.shape

        if row_num != col_num:
            raise ArgError("only support N*N array")

        dim = row_num

        layers = dim // 2

        for layer in range(layers):
            start = layer
            end = dim - 1 - layer

            for offset in range(end - start):
                tmp = a[start, start + offset]
                a[start, start + offset] = a[end - offset, start]
                a[end - offset, start] = a[end, end - offset]
                a[end, end - offset] = a[start + offset, end]
                a[start + offset, end] = tmp

        return a
Ejemplo n.º 2
0
def safe_log(x: np.array):
    """
    Returns the log of x. If x contains a zero value, adds 1 to all values
    """
    assert type(x) == np.ndarray, f'x is of type {type(x)}'

    if x.all():
        y = np.log(x)
    else:
        y = np.log(x + 1)

    assert not np.isinf(y).any(), f'Infinite values found in y!'

    return y
Ejemplo n.º 3
0
    def rotate(a: np.array, *, dtype=int):
        """  Rotate for M*N array, this is equivalent to numpy.rot90(a, 3)
        :array: M*N numpy array
        :return: rotated numpy array

        Complexity:
        Time  : O(rc)
        Space : O(rc)
        """

        if not a.all():
            raise ArgError()

        row_num, col_num = a.shape[::-1]

        rotated_array = np.empty(shape=[row_num, col_num], dtype=dtype)

        for index, v in np.ndenumerate(a):
            r, c = index
            rotated_array[c, col_num - 1 - r] = v

        return rotated_array
Ejemplo n.º 4
0
    def property_function(bin_str: np.array) -> float:
        """Compute measure based on Lempel_Ziv complexity. 

        Same measure as in Dingle, Camargo, and Louis (2018),
        'Input–output maps are strongly biased towards simple outputs', 
        See Supplementary Note 1, p. 10.

        Args:
            bin_str: A numpy array of shape (1,) with Boolean values.
                Represents the meaning (extension) of an expression.
                Entry i represents whether the expression is true
                in model i (the i'th model in the enumeration of 
                models in the universe).

        Returns:
            A single number (float).

        """
        expr_len = len(bin_str)
        if bin_str.all() or np.invert(bin_str).all():
            return log2(expr_len)
        lz_expr = lz(bin_str.tobytes())
        lz_rev_expr = lz(np.flip(bin_str).tobytes())
        return log2(expr_len) * (lz_expr + lz_rev_expr) / 2
    def get_ensemble_knots(self,
                           n_i_knots: int,
                           spline_data: np.array,
                           observed: np.array,
                           spline_options: Dict,
                           terminal_days: int = 4) -> List[np.array]:
        # # number of submodels
        # N = n_i_knots * 4
        # N = max(28, N)
        N = 40

        # where are our fixed outer points
        if observed.sum() < 100:
            #start_boundary_pctile = terminal_days / 100
            end_boundary_pctile = 1. - (terminal_days / 100)
            min_interval = terminal_days / 100
        else:
            # start_boundary_pctile,
            end_boundary_pctile = self.find_pctile(
                spline_data[observed], terminal_days,
                spline_options['spline_knots_type'])
            min_interval = terminal_days / observed.sum()
        start_boundary_pctile = 0.

        # fix first and last interior knots as specified
        n_intervals = n_i_knots + 1
        k_start = 0.
        k_end = 1.
        if n_i_knots >= 3:
            if np.quantile(spline_data[observed],
                           start_boundary_pctile) > spline_data.min():
                n_intervals -= 1
                k_start = start_boundary_pctile + min_interval
            if np.quantile(spline_data[observed],
                           end_boundary_pctile) < spline_data.max():
                n_intervals -= 1
                k_end = end_boundary_pctile - min_interval

        # sample - force first 50% of knots to be in placed first 50% of domain; same of second (for speed)
        b = np.array([[k_start, k_end / 2]] * ((n_intervals - 1) - int((n_intervals - 1) / 2)) + \
                     [[k_end / 2, k_end]] * int((n_intervals - 1) / 2))
        d = np.array([[min_interval, 1]] * n_intervals)
        ensemble_knots = utils.sample_knots(n_intervals, b=b, d=d, N=N)
        if k_start > 0.:
            ensemble_knots = np.insert(ensemble_knots, 1,
                                       start_boundary_pctile, 1)
        if k_end < 1.:
            ensemble_knots = np.insert(ensemble_knots, -1, end_boundary_pctile,
                                       1)

        # rescale to observed
        if not observed.all():
            if spline_options['spline_knots_type'] != 'domain':
                raise ValueError(
                    'Expecting `spline_knots_type` domain for knot rescaling (stage 2 model).'
                )
            ensemble_knots = rescale_k(spline_data[observed], spline_data,
                                       ensemble_knots)

        # make sure we have unique knots
        if spline_options['spline_knots_type'] == 'frequency':
            _ensemble_knots = []
            for knots in ensemble_knots:
                if np.unique(np.quantile(spline_data,
                                         knots)).size == knots.size:
                    _ensemble_knots.append(knots)
            ensemble_knots = np.vstack(_ensemble_knots)

            # flag if no fully unique knot options (i.e., entries w/ duplicates eliminated in previous step)
            if ensemble_knots.size == 0:
                raise ValueError(
                    'Knot options do not find unique data values (frequency).')

        return ensemble_knots