Get a reduced structure.

        Args:
            reduction_algo (str): The lattice reduction algorithm to use.
                Currently supported options are "niggli" or "LLL".
764632
def get_reduced_structure(self, reduction_algo="niggli"):
        
        if reduction_algo == "niggli":
            reduced_latt = self._lattice.get_niggli_reduced_lattice()
        elif reduction_algo == "LLL":
            reduced_latt = self._lattice.get_lll_reduced_lattice()
        else:
            raise ValueError("Invalid reduction algo : {}"
                             .format(reduction_algo))

        if reduced_latt != self.lattice:
            return self.__class__(reduced_latt, self.species_and_occu,
                                  self.cart_coords,
                                  coords_are_cartesian=True, to_unit_cell=True,
                                  site_properties=self.site_properties, charge=self._charge)
        else:
            return self.copy()
686093
def _reduce_method(cls, func):
        

        def wrapped_func(self, **kwargs):
            from .dataset import Dataset
            reduced = OrderedDict()
            for key, da in self.obj.data_vars.items():
                if self.dim in da.dims:
                    reduced[key] = getattr(self.rollings[key],
                                           func.__name__)(**kwargs)
                else:
                    reduced[key] = self.obj[key]
            return Dataset(reduced, coords=self.obj.coords)
        return wrapped_func
167250
def reduce_tree(node, parent=None):
    

    new_node = None
    #switch on the node type
    if node.type == syms.Matcher:
        #skip
        node = node.children[0]

    if node.type == syms.Alternatives  :
        #2 cases
        if len(node.children) <= 2:
            #just a single 'Alternative', skip this node
            new_node = reduce_tree(node.children[0], parent)
        else:
            #real alternatives
            new_node = MinNode(type=TYPE_ALTERNATIVES)
            #skip odd children('|' tokens)
            for child in node.children:
                if node.children.index(child)%2:
                    continue
                reduced = reduce_tree(child, new_node)
                if reduced is not None:
                    new_node.children.append(reduced)
    elif node.type == syms.Alternative:
        if len(node.children) > 1:

            new_node = MinNode(type=TYPE_GROUP)
            for child in node.children:
                reduced = reduce_tree(child, new_node)
                if reduced:
                    new_node.children.append(reduced)
            if not new_node.children:
                # delete the group if all of the children were reduced to None
                new_node = None

        else:
            new_node = reduce_tree(node.children[0], parent)

    elif node.type == syms.Unit:
        if (isinstance(node.children[0], pytree.Leaf) and
            node.children[0].value == '('):
            #skip parentheses
            return reduce_tree(node.children[1], parent)
        if ((isinstance(node.children[0], pytree.Leaf) and
               node.children[0].value == '[')
               or
               (len(node.children)>1 and
               hasattr(node.children[1], "value") and
               node.children[1].value == '[')):
            #skip whole unit if its optional
            return None

        leaf = True
        details_node = None
        alternatives_node = None
        has_repeater = False
        repeater_node = None
        has_variable_name = False

        for child in node.children:
            if child.type == syms.Details:
                leaf = False
                details_node = child
            elif child.type == syms.Repeater:
                has_repeater = True
                repeater_node = child
            elif child.type == syms.Alternatives:
                alternatives_node = child
            if hasattr(child, 'value') and child.value == '=': # variable name
                has_variable_name = True

        #skip variable name
        if has_variable_name:
            #skip variable name, '='
            name_leaf = node.children[2]
            if hasattr(name_leaf, 'value') and name_leaf.value == '(':
                # skip parenthesis
                name_leaf = node.children[3]
        else:
            name_leaf = node.children[0]

        #set node type
        if name_leaf.type == token_labels.NAME:
            #(python) non-name or wildcard
            if name_leaf.value == 'any':
                new_node = MinNode(type=TYPE_ANY)
            else:
                if hasattr(token_labels, name_leaf.value):
                    new_node = MinNode(type=getattr(token_labels, name_leaf.value))
                else:
                    new_node = MinNode(type=getattr(pysyms, name_leaf.value))

        elif name_leaf.type == token_labels.STRING:
            #(python) name or character; remove the apostrophes from
            #the string value
            name = name_leaf.value.strip("'")
            if name in tokens:
                new_node = MinNode(type=tokens[name])
            else:
                new_node = MinNode(type=token_labels.NAME, name=name)
        elif name_leaf.type == syms.Alternatives:
            new_node = reduce_tree(alternatives_node, parent)

        #handle repeaters
        if has_repeater:
            if repeater_node.children[0].value == '*':
                #reduce to None
                new_node = None
            elif repeater_node.children[0].value == '+':
                #reduce to a single occurence i.e. do nothing
                pass
            else:
                #TODO: handle {min, max} repeaters
                raise NotImplementedError
                pass

        #add children
        if details_node and new_node is not None:
            for child in details_node.children[1:-1]:
                #skip '<', '>' markers
                reduced = reduce_tree(child, new_node)
                if reduced is not None:
                    new_node.children.append(reduced)
    if new_node:
        new_node.parent = parent
    return new_node
111386
def _reduce(self, op, name, axis=0, skipna=True, numeric_only=None,
                filter_type=None, **kwds):
        
        delegate = self._values

        if axis is not None:
            self._get_axis_number(axis)

        if isinstance(delegate, Categorical):
            # TODO deprecate numeric_only argument for Categorical and use
            # skipna as well, see GH25303
            return delegate._reduce(name, numeric_only=numeric_only, **kwds)
        elif isinstance(delegate, ExtensionArray):
            # dispatch to ExtensionArray interface
            return delegate._reduce(name, skipna=skipna, **kwds)
        elif is_datetime64_dtype(delegate):
            # use DatetimeIndex implementation to handle skipna correctly
            delegate = DatetimeIndex(delegate)

        # dispatch to numpy arrays
        elif isinstance(delegate, np.ndarray):
            if numeric_only:
                raise NotImplementedError('Series.{0} does not implement '
                                          'numeric_only.'.format(name))
            with np.errstate(all='ignore'):
                return op(delegate, skipna=skipna, **kwds)

        # TODO(EA) dispatch to Index
        # remove once all internals extension types are
        # moved to ExtensionArrays
        return delegate._reduce(op=op, name=name, axis=axis, skipna=skipna,
                                numeric_only=numeric_only,
                                filter_type=filter_type, **kwds)
1005752
def _get_augmented_label_matrix(self, L, higher_order=False):
        
        # Create a helper data structure which maps cliques (as tuples of member
        # sources) --> {start_index, end_index, maximal_cliques}, where
        # the last value is a set of indices in this data structure
        self.c_data = {}
        for i in range(self.m):
            self.c_data[i] = {
                "start_index": i * self.k,
                "end_index": (i + 1) * self.k,
                "max_cliques": set(
                    [
                        j
                        for j in self.c_tree.nodes()
                        if i in self.c_tree.node[j]["members"]
                    ]
                ),
            }

        L_ind = self._create_L_ind(L)

        # Get the higher-order clique statistics based on the clique tree
        # First, iterate over the maximal cliques (nodes of c_tree) and
        # separator sets (edges of c_tree)
        if higher_order:
            L_aug = np.copy(L_ind)
            for item in chain(self.c_tree.nodes(), self.c_tree.edges()):
                if isinstance(item, int):
                    C = self.c_tree.node[item]
                    C_type = "node"
                elif isinstance(item, tuple):
                    C = self.c_tree[item[0]][item[1]]
                    C_type = "edge"
                else:
                    raise ValueError(item)
                members = list(C["members"])
                nc = len(members)

                # If a unary maximal clique, just store its existing index
                if nc == 1:
                    C["start_index"] = members[0] * self.k
                    C["end_index"] = (members[0] + 1) * self.k

                # Else add one column for each possible value
                else:
                    L_C = np.ones((self.n, self.k ** nc))
                    for i, vals in enumerate(product(range(self.k), repeat=nc)):
                        for j, v in enumerate(vals):
                            L_C[:, i] *= L_ind[:, members[j] * self.k + v]

                    # Add to L_aug and store the indices
                    if L_aug is not None:
                        C["start_index"] = L_aug.shape[1]
                        C["end_index"] = L_aug.shape[1] + L_C.shape[1]
                        L_aug = np.hstack([L_aug, L_C])
                    else:
                        C["start_index"] = 0
                        C["end_index"] = L_C.shape[1]
                        L_aug = L_C

                    # Add to self.c_data as well
                    id = tuple(members) if len(members) > 1 else members[0]
                    self.c_data[id] = {
                        "start_index": C["start_index"],
                        "end_index": C["end_index"],
                        "max_cliques": set([item]) if C_type == "node" else set(item),
                    }
            return L_aug
        else:
            return L_ind
588435
def get_nonmagnetic_structure(self, make_primitive=True):
        

        structure = self.structure.copy()
        structure.remove_site_property("magmom")

        if make_primitive:
            structure = structure.get_primitive_structure()

        return structure
45537
private DenseTensor reduceDimensions(Collection<Integer> dimensionsToEliminate,
      boolean useSum, Backpointers backpointers) {
    SortedSet<Integer> dimensionsToKeep = Sets.newTreeSet(Ints.asList(getDimensionNumbers()));
    dimensionsToKeep.removeAll(dimensionsToEliminate);

    int[] myDimensionNumbers = getDimensionNumbers();
    int[] myDimensionSizes = getDimensionSizes();
    List<Integer> dimensionNumsToKeep = Lists.newArrayList();
    List<Integer> dimensionSizesToKeep = Lists.newArrayList();
    List<Integer> dimensionNumsToEliminate = Lists.newArrayList();
    List<Integer> dimensionSizesToEliminate = Lists.newArrayList();
    for (int i = 0; i < myDimensionNumbers.length; i++) {
      if (!dimensionsToEliminate.contains(myDimensionNumbers[i])) {
        dimensionNumsToKeep.add(myDimensionNumbers[i]);
        dimensionSizesToKeep.add(myDimensionSizes[i]);
      } else {
        dimensionNumsToEliminate.add(myDimensionNumbers[i]);
        dimensionSizesToEliminate.add(myDimensionSizes[i]);
      }
    }

    DenseTensorBuilder outputBuilder = new DenseTensorBuilder(Ints.toArray(dimensionNumsToKeep),
        Ints.toArray(dimensionSizesToKeep));
    // Optionally return the list of keynums which determined the values
    // in the returned tensor.
    long[] newBackpointerNums = null;
    long[] oldBackpointerNums = null;
    if (backpointers != null) {
      newBackpointerNums = new long[outputBuilder.values.length];
      oldBackpointerNums = new long[outputBuilder.values.length];
    }

    // Maps a key of the reduced tensor into a partial key of this.
    int[] dimensionMapping = getDimensionMapping(outputBuilder.getDimensionNumbers());
    int[] partialKey = new int[getDimensionNumbers().length];
    Arrays.fill(partialKey, -1);
    Iterator<KeyValue> otherKeyValues = outputBuilder.keyValueIterator();

    int backpointerIndex = 0;
    while (otherKeyValues.hasNext()) {
      KeyValue otherKeyValue = otherKeyValues.next();
      for (int i = 0; i < otherKeyValue.getKey().length; i++) {
        partialKey[dimensionMapping[i]] = otherKeyValue.getKey()[i];
      }

      Iterator<int[]> myKeyIterator = new SliceIndexIterator(getDimensionSizes(), partialKey);
      double resultVal = (useSum) ? 0.0 : Double.NEGATIVE_INFINITY;
      long backpointerKeyNum = -1;
      while (myKeyIterator.hasNext()) {
        if (useSum) {
          resultVal += getByDimKey(myKeyIterator.next());
        } else {
          int[] nextKey = myKeyIterator.next();
          double keyVal = getByDimKey(nextKey);
          if (keyVal > resultVal) {
            resultVal = keyVal;
            backpointerKeyNum = dimKeyToKeyNum(nextKey);
          }
        }
      }
      outputBuilder.put(otherKeyValue.getKey(), resultVal);

      if (backpointers != null) {
        newBackpointerNums[backpointerIndex] = outputBuilder.dimKeyToKeyNum(otherKeyValue.getKey());
        oldBackpointerNums[backpointerIndex] = backpointerKeyNum;
        backpointerIndex++;
      }
    }

    if (backpointers != null) {
      backpointers.setBackpointers(newBackpointerNums, oldBackpointerNums, backpointerIndex, this);
    }

    return outputBuilder.buildNoCopy();
  }
1339612
def build_reduce(function: Callable[[Any, Any], Any] = None, *,
                 init: Any = NONE):
    
    _init = init

    def _build_reduce(function: Callable[[Any, Any], Any]):
        @wraps(function)
        def _wrapper(init=NONE) -> Reduce:
            init = _init if init is NONE else init
            if init is NONE:
                raise TypeError('init argument has to be defined')
            return Reduce(function, init=init)
        return _wrapper

    if function:
        return _build_reduce(function)

    return _build_reduce
153796
def reduce_cpu(f, x, axes, dtype):
    """"""
    axes = _get_axes(axes, x.ndim)
    if not axes:
        return x

    permute = [n for n in range(x.ndim) if n not in axes]
    permute = axes + permute

    T = x.transpose(permute=permute)

    N = len(axes)
    t = T.type.at(N, dtype=dtype)
    acc = x.empty(t, device=x.device)

    if f.identity is not None:
        _copyto(acc, f.identity)
        tl = T
    elif N == 1 and T.type.shape[0] > 0:
        hd, tl = T[0], T[1:]
        acc[()] = hd
    else:
        raise ValueError(
            "reduction not possible for function without an identity element")

    return fold(f, acc, tl)
391209
def apply_transformation(self, structure, return_ranked_list=False):
        

        if not structure.is_ordered:
            raise ValueError("Create an ordered approximation of "
                             "your  input structure first.")

        # retrieve order parameters
        order_parameters = [MagOrderParameterConstraint.from_dict(op_dict)
                            for op_dict in self.order_parameter]
        # add dummy species on which to perform enumeration
        structure = self._add_dummy_species(structure, order_parameters)

        # trivial case
        if structure.is_ordered:
            structure = self._remove_dummy_species(structure)
            return [structure] if return_ranked_list > 1 else structure

        enum_kwargs = self.enum_kwargs.copy()

        enum_kwargs["min_cell_size"] = max(
            int(self.determine_min_cell(structure)),
            enum_kwargs.get("min_cell_size", 1)
        )

        if enum_kwargs.get("max_cell_size", None):
            if enum_kwargs["min_cell_size"] > enum_kwargs["max_cell_size"]:
                warnings.warn("Specified max cell size ({}) is smaller "
                              "than the minimum enumerable cell size ({}), "
                              "changing max cell size to {}".format(enum_kwargs["max_cell_size"],
                                                                    enum_kwargs["min_cell_size"],
                                                                    enum_kwargs["min_cell_size"]))
                enum_kwargs["max_cell_size"] = enum_kwargs["min_cell_size"]
        else:
            enum_kwargs["max_cell_size"] = enum_kwargs["min_cell_size"]

        t = EnumerateStructureTransformation(**enum_kwargs)

        alls = t.apply_transformation(structure,
                                      return_ranked_list=return_ranked_list)

        # handle the fact that EnumerateStructureTransformation can either
        # return a single Structure or a list
        if isinstance(alls, Structure):
            # remove dummy species and replace Spin.up or Spin.down
            # with spin magnitudes given in mag_species_spin arg
            alls = self._remove_dummy_species(alls)
            alls = self._add_spin_magnitudes(alls)
        else:
            for idx, _ in enumerate(alls):
                alls[idx]["structure"] = self._remove_dummy_species(alls[idx]["structure"])
                alls[idx]["structure"] = self._add_spin_magnitudes(alls[idx]["structure"])

        try:
            num_to_return = int(return_ranked_list)
        except ValueError:
            num_to_return = 1

        if num_to_return == 1 or not return_ranked_list:
            return alls[0]["structure"] if num_to_return else alls

        # remove duplicate structures and group according to energy model
        m = StructureMatcher(comparator=SpinComparator())
        key = lambda x: SpacegroupAnalyzer(x, 0.1).get_space_group_number()
        out = []
        for _, g in groupby(sorted([d["structure"] for d in alls],
                                   key=key), key):
            g = list(g)
            grouped = m.group_structures(g)
            out.extend([{"structure": g[0],
                         "energy": self.energy_model.get_energy(g[0])}
                        for g in grouped])

        self._all_structures = sorted(out, key=lambda d: d["energy"])

        return self._all_structures[0:num_to_return]
202923
def _get_struct_cxformwithalpha(self):
        """"""
        obj = _make_object("CXformWithAlpha")
        bc = BitConsumer(self._src)

        obj.HasAddTerms = bc.u_get(1)
        obj.HasMultTerms = bc.u_get(1)
        obj.NBits = nbits = bc.u_get(4)

        if obj.HasMultTerms:
            obj.RedMultTerm = bc.s_get(nbits)
            obj.GreenMultTerm = bc.s_get(nbits)
            obj.BlueMultTerm = bc.s_get(nbits)
            obj.AlphaMultTerm = bc.s_get(nbits)

        if obj.HasAddTerms:
            obj.RedAddTerm = bc.s_get(nbits)
            obj.GreenAddTerm = bc.s_get(nbits)
            obj.BlueAddTerm = bc.s_get(nbits)
            obj.AlphaAddTerm = bc.s_get(nbits)

        return obj
292251
def getalgo(self, operation, name):
        ''''''
        if operation not in self._algorithms:
            raise NotAvailable('{0} not registered.'.format(operation))
        oper = self._algorithms[operation]
        try:
            return oper[name]
        except KeyError:
            raise NotAvailable('{0} algorithm {1} not registered.'
                               .format(operation, name))
1134973
def get_refined_structure(self):
        
        # Atomic positions have to be specified by scaled positions for spglib.
        lattice, scaled_positions, numbers \
            = spglib.refine_cell(self._cell, self._symprec, self._angle_tol)

        species = [self._unique_species[i - 1] for i in numbers]
        s = Structure(lattice, species, scaled_positions)
        return s.get_sorted_structure()
229407
def connected_subgraphs(self, directed=True, ordered=False):
    '''
    '''
    num_ccs, labels = self.connected_components(directed=directed)
    # check the trivial case first
    if num_ccs == 1:
      yield self
      raise StopIteration
    if ordered:
      # sort by descending size (num vertices)
      order = np.argsort(np.bincount(labels))[::-1]
    else:
      order = range(num_ccs)

    # don't use self.subgraph() here, because we can reuse adj
    adj = self.matrix('dense', 'csr', 'csc')
    for c in order:
      mask = labels == c
      sub_adj = adj[mask][:,mask]
      yield self.__class__.from_adj_matrix(sub_adj)
148729
def structure_to_abivars(structure, **kwargs):
    
    if not structure.is_ordered:
        raise ValueError("""\
Received disordered structure with partial occupancies that cannot be converted into an Abinit input
Please use OrderDisorderedStructureTransformation or EnumerateStructureTransformation
to build an appropriate supercell from partial occupancies or alternatively use the Virtual Crystal Approximation.""")

    types_of_specie = structure.types_of_specie
    natom = structure.num_sites

    znucl_type = [specie.number for specie in types_of_specie]
    znucl_atoms = structure.atomic_numbers

    typat = np.zeros(natom, np.int)
    for atm_idx, site in enumerate(structure):
        typat[atm_idx] = types_of_specie.index(site.specie) + 1

    rprim = ArrayWithUnit(structure.lattice.matrix, "ang").to("bohr")
    angdeg = structure.lattice.angles
    xred = np.reshape([site.frac_coords for site in structure], (-1, 3))

    # Set small values to zero. This usually happens when the CIF file
    # does not give structure parameters with enough digits.
    rprim = np.where(np.abs(rprim) > 1e-8, rprim, 0.0)
    xred = np.where(np.abs(xred) > 1e-8, xred, 0.0)

    # Info on atoms.
    d = dict(
        natom=natom,
        ntypat=len(types_of_specie),
        typat=typat,
        znucl=znucl_type,
        xred=xred,
    )

    # Add info on the lattice.
    # Should we use (rprim, acell) or (angdeg, acell) to specify the lattice?
    geomode = kwargs.pop("geomode", "rprim")
    if geomode == "automatic":
        geomode = "rprim"
        if structure.lattice.is_hexagonal: # or structure.lattice.is_rhombohedral
            geomode = "angdeg"
            angdeg = structure.lattice.angles
            # Here one could polish a bit the numerical values if they are not exact.
            # Note that in pmg the angles are 12, 20, 01 while in Abinit 12, 02, 01
            # One should make sure that the orientation is preserved (see Curtarolo's settings)

    if geomode == "rprim":
        d.update(
            acell=3 * [1.0],
            rprim=rprim,
        )

    elif geomode == "angdeg":
        d.update(
            acell=ArrayWithUnit(structure.lattice.abc, "ang").to("bohr"),
            angdeg=angdeg,
        )
    else:
        raise ValueError("Wrong value for geomode: %s" % geomode)

    return d
1284201
def get_substructure_mapping(self, other, limit=1):
        
        i = self._matcher(other).subgraph_isomorphisms_iter()
        if limit == 1:
            m = next(i, None)
            if m:
                return {v: k for k, v in m.items()}
            return
        elif limit == 0:
            return ({v: k for k, v in m.items()} for m in i)
        return [{v: k for k, v in m.items()} for m in islice(i, limit)]
854500
def reduced_chi2(self, model, error_map=0):
        
        chi2 = self.reduced_residuals(model, error_map)
        return np.sum(chi2**2) / self.num_data_evaluate()