Instruction:
Explain what the following Python 3 code does
def fill_jacobian_column(self, jaccol, coordinates):
        q, g = self.icfn(coordinates[list(self.indexes)], 1)
        for i, j in enumerate(self.indexes):
            jaccol[3*j:3*j+3] += g[i]
        return jaccol

Response: Fill in a column of the Jacobian.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def compute_similarity(a, b, margin=1.0, cutoff=10.0):
    return similarity_measure(
        a.table_labels, a.table_distances,
        b.table_labels, b.table_distances,
        margin, cutoff
    )

Response: Compute the similarity between two molecules based on their descriptors.


Instruction:
Can you generate the documentation for the following Python 3 function
def from_molecule(cls, molecule, labels=None):
        if labels is None:
            labels = molecule.numbers
        return cls(molecule.distance_matrix, labels)

Response: Initialize a similarity descriptor from a Molecule object.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def from_molecular_graph(cls, molecular_graph, labels=None):
        if labels is None:
            labels = molecular_graph.numbers.astype(int)
        return cls(molecular_graph.distances, labels)

Response: Initialize a similarity descriptor from a MolecularGraph object.


Instruction:
Write a Python 3 script to
initialize a similarity descriptor from a set of coordinates and labels

Response:
def from_coordinates(cls, coordinates, labels):
        """Initialize a similarity descriptor

           Arguments:
             coordinates  --  a Nx3 numpy array
             labels  --  a list with integer labels used to identify atoms of
                         the same type
        """
        from molmod.ext import molecules_distance_matrix
        distance_matrix = molecules_distance_matrix(coordinates)
        return cls(distance_matrix, labels)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def load_chk(filename):
    '''Load a checkpoint file

       Argument:
        | filename  --  the file to load from

       The return value is a dictionary whose keys are field labels and the
       values can be None, string, integer, float, boolean or an array of
       strings, integers, booleans or floats.

       The file format is similar to the Gaussian fchk format, but has the extra
       feature that the shapes of the arrays are also stored.
    '''
    with open(filename) as f:
        result = {}
        while True:
            line = f.readline()
            if line == '':
                break
            if len(line) < 54:
                raise IOError('Header lines must be at least 54 characters long.')
            key = line[:40].strip()
            kind = line[47:52].strip()
            value = line[53:-1] # discard newline
            if kind == 'str':
                result[key] = value
            elif kind == 'int':
                result[key] = int(value)
            elif kind == 'bln':
                result[key] = value.lower() in ['true', '1', 'yes']
            elif kind == 'flt':
                result[key] = float(value)
            elif kind[3:5] == 'ar':
                if kind[:3] == 'str':
                    dtype = np.dtype('U22')
                elif kind[:3] == 'int':
                    dtype = int
                elif kind[:3] == 'bln':
                    dtype = bool
                elif kind[:3] == 'flt':
                    dtype = float
                else:
                    raise IOError('Unsupported kind: %s' % kind)
                shape = tuple(int(i) for i in value.split(','))
                array = np.zeros(shape, dtype)
                if array.size > 0:
                    work = array.ravel()
                    counter = 0
                    while True:
                        short = f.readline().split()
                        if len(short) == 0:
                            raise IOError('Insufficient data')
                        for s in short:
                            if dtype == bool:
                                work[counter] = s.lower() in ['true', '1', 'yes']
                            elif callable(dtype):
                                work[counter] = dtype(s)
                            else:
                                work[counter] = s
                            counter += 1
                            if counter == array.size:
                                break
                        if counter == array.size:
                            break
                result[key] = array
            elif kind == 'none':
                result[key] = None
            else:
                raise IOError('Unsupported kind: %s' % kind)
    return result

Response: Load a checkpoint file from a checkpoint file.


Instruction:
How would you explain what the following Python 3 function does
def dump_chk(filename, data):
    '''Dump a checkpoint file

       Argument:
        | filename  --  the file to write to
        | data  -- a dictionary whose keys are field labels and the values can
                   be None, string, integer, float, boolean, an array/list of
                   strings, integers, floats or booleans.

       The file format is similar to the Gaussian fchk format, but has the extra
       feature that the shapes of the arrays are also stored.
    '''
    with open(filename, 'w') as f:
        for key, value in sorted(data.items()):
            if not isinstance(key, str):
                raise TypeError('The keys must be strings.')
            if len(key) > 40:
                raise ValueError('Key strings cannot be longer than 40 characters.')
            if '\n' in key:
                raise ValueError('Key strings cannot contain newlines.')
            if isinstance(value, str):
                if len(value) > 256:
                    raise ValueError('Only small strings are supported (256 chars).')
                if '\n' in value:
                    raise ValueError('The string cannot contain new lines.')
                print('%40s  kind=str   %s' % (key.ljust(40), value), file=f)
            elif isinstance(value, bool):
                print('%40s  kind=bln   %s' % (key.ljust(40), value), file=f)
            elif isinstance(value, (int, np.integer)):
                print('%40s  kind=int   %i' % (key.ljust(40), value), file=f)
            elif isinstance(value, float):
                print('%40s  kind=flt   %22.15e' % (key.ljust(40), value), file=f)
            elif isinstance(value, np.ndarray) or isinstance(value, list) or \
                 isinstance(value, tuple):
                if isinstance(value, list) or isinstance(value, tuple):
                    value = np.array(value)
                if value.dtype.fields is not None:
                    raise TypeError('Arrays with fields are not supported.')
                shape_str = ','.join(str(i) for i in value.shape)
                if issubclass(value.dtype.type, (str, np.unicode, np.bytes_)):
                    value = value.astype(np.unicode)
                    for cell in value.flat:
                        if len(cell) >= 22:
                            raise ValueError('In case of string arrays, a string may contain at most 21 characters.')
                        if ' ' in cell or '\n' in cell:
                            raise ValueError('In case of string arrays, a string may not contain spaces or new lines.')
                    print('%40s  kind=strar %s' % (key.ljust(40), shape_str), file=f)
                    format_str = '%22s'
                elif issubclass(value.dtype.type, np.integer):
                    print('%40s  kind=intar %s' % (key.ljust(40), shape_str), file=f)
                    format_str = '%22i'
                elif issubclass(value.dtype.type, np.bool_):
                    print('%40s  kind=blnar %s' % (key.ljust(40), shape_str), file=f)
                    format_str = '%22s'
                elif issubclass(value.dtype.type, float):
                    print('%40s  kind=fltar %s' % (key.ljust(40), shape_str), file=f)
                    format_str = '%22.15e'
                else:
                    raise TypeError('Numpy array type %s not supported.' % value.dtype.type)
                short_len = 4
                short = []
                for x in value.ravel():
                    short.append(x)
                    if len(short) == 4:
                        print(' '.join(format_str  % s for s in short), file=f)
                        short = []
                if len(short) > 0:
                    print(' '.join(format_str  % s for s in short), file=f)
            elif value is None:
                print('%40s  kind=none   None' % key.ljust(40), file=f)
            else:
                raise TypeError('Type %s not supported.' % type(value))

Response: Dump a checkpoint file to a file.


Instruction:
Implement a function in Python 3 to
clear the contents of the data structure

Response:
def clear(self):
        """Clear the contents of the data structure"""
        self.title = None
        self.numbers = np.zeros(0, int)
        self.atom_types = [] # the atom_types in the second column, used to associate ff parameters
        self.charges = [] # ff charges
        self.names = [] # a name that is unique for the molecule composition and connectivity
        self.molecules = np.zeros(0, int) # a counter for each molecule
        self.bonds = np.zeros((0, 2), int)
        self.bends = np.zeros((0, 3), int)
        self.dihedrals = np.zeros((0, 4), int)
        self.impropers = np.zeros((0, 4), int)

        self.name_cache = {}


Instruction:
Can you create a Python 3 function that
reads a PSF file into the internal dictionary.

Response:
def read_from_file(self, filename):
        """Load a PSF file"""
        self.clear()
        with open(filename) as f:
            # A) check the first line
            line = next(f)
            if not line.startswith("PSF"):
                raise FileFormatError("Error while reading: A PSF file must start with a line 'PSF'.")
            # B) read in all the sections, without interpreting them
            current_section = None
            sections = {}
            for line in f:
                line = line.strip()
                if line == "":
                    continue
                elif "!N" in line:
                    words = line.split()
                    current_section = []
                    section_name = words[1][2:]
                    if section_name.endswith(":"):
                        section_name = section_name[:-1]
                    sections[section_name] = current_section
                else:
                    current_section.append(line)
        # C) interpret the supported sections
        # C.1) The title
        self.title = sections['TITLE'][0]
        molecules = []
        numbers = []
        # C.2) The atoms and molecules
        for line in sections['ATOM']:
            words = line.split()
            self.atom_types.append(words[5])
            self.charges.append(float(words[6]))
            self.names.append(words[3])
            molecules.append(int(words[2]))
            atom = periodic[words[4]]
            if atom is None:
                numbers.append(0)
            else:
                numbers.append(periodic[words[4]].number)
        self.molecules = np.array(molecules)-1
        self.numbers = np.array(numbers)
        self.charges = np.array(self.charges)
        # C.3) The bonds section
        tmp = []
        for line in sections['BOND']:
            tmp.extend(int(word) for word in line.split())
        self.bonds = np.reshape(np.array(tmp), (-1, 2))-1
        # C.4) The bends section
        tmp = []
        for line in sections['THETA']:
            tmp.extend(int(word) for word in line.split())
        self.bends = np.reshape(np.array(tmp), (-1, 3))-1
        # C.5) The dihedral section
        tmp = []
        for line in sections['PHI']:
            tmp.extend(int(word) for word in line.split())
        self.dihedrals = np.reshape(np.array(tmp), (-1, 4))-1
        # C.6) The improper section
        tmp = []
        for line in sections['IMPHI']:
            tmp.extend(int(word) for word in line.split())
        self.impropers = np.reshape(np.array(tmp), (-1, 4))-1


Instruction:
Write a Python 3 script for
converting a molecular graph into a unique name

Response:
def _get_name(self, graph, group=None):
        """Convert a molecular graph into a unique name

           This method is not sensitive to the order of the atoms in the graph.
        """
        if group is not None:
            graph = graph.get_subgraph(group, normalize=True)

        fingerprint = graph.fingerprint.tobytes()
        name = self.name_cache.get(fingerprint)
        if name is None:
            name = "NM%02i" % len(self.name_cache)
            self.name_cache[fingerprint] = name
        return name


Instruction:
How would you code a function in Python 3 to
dump the data structure to a file - like object

Response:
def dump(self, f):
        """Dump the data structure to a file-like object"""
        # header
        print("PSF", file=f)
        print(file=f)

        # title
        print("      1 !NTITLE", file=f)
        print(self.title, file=f)
        print(file=f)

        # atoms
        print("% 7i !NATOM" % len(self.numbers), file=f)
        if len(self.numbers) > 0:
            for index, (number, atom_type, charge, name, molecule) in enumerate(zip(self.numbers, self.atom_types, self.charges, self.names, self.molecules)):
                atom = periodic[number]
                print("% 7i % 4s % 4i NAME % 6s % 6s % 8.4f % 12.6f 0" % (
                    index + 1,
                    name,
                    molecule + 1,
                    atom.symbol,
                    atom_type,
                    charge,
                    atom.mass/unified,
                ), file=f)
        print(file=f)

        # bonds
        print("% 7i !NBOND" % len(self.bonds), file=f)
        if len(self.bonds) > 0:
            tmp = []
            for bond in self.bonds:
                tmp.extend(bond+1)
                if len(tmp) >= 8:
                    print(" ".join("% 7i" % v for v in tmp[:8]), file=f)
                    tmp = tmp[8:]
            if len(tmp) > 0:
                print(" ".join("% 7i" % v for v in tmp), file=f)
        print(file=f)

        # bends
        print("% 7i !NTHETA" % len(self.bends), file=f)
        if len(self.bends) > 0:
            tmp = []
            for bend in self.bends:
                tmp.extend(bend+1)
                if len(tmp) >= 9:
                    print(" " + (" ".join("% 6i" % v for v in tmp[:9])), file=f)
                    tmp = tmp[9:]
            if len(tmp) > 0:
                print(" " + (" ".join("% 6i" % v for v in tmp)), file=f)
        print(file=f)

        # dihedrals
        print("% 7i !NPHI" % len(self.dihedrals), file=f)
        if len(self.dihedrals) > 0:
            tmp = []
            for dihedral in self.dihedrals:
                tmp.extend(dihedral+1)
                if len(tmp) >= 8:
                    print(" " + (" ".join("% 6i" % v for v in tmp[:8])), file=f)
                    tmp = tmp[8:]
            if len(tmp) > 0:
                print(" " + (" ".join("% 6i" % v for v in tmp)), file=f)
        print(file=f)

        # impropers
        print("% 7i !NIMPHI" % len(self.impropers), file=f)
        if len(self.impropers) > 0:
            tmp = []
            for improper in self.impropers:
                tmp.extend(improper+1)
                if len(tmp) >= 8:
                    print(" " + (" ".join("% 6i" % v for v in tmp[:8])), file=f)
                    tmp = tmp[8:]
            if len(tmp) > 0:
                print(" " + (" ".join("% 6i" % v for v in tmp)), file=f)
        print(file=f)

        # not implemented fields
        print("      0 !NDON", file=f)
        print(file=f)
        print("      0 !NNB", file=f)
        print(file=f)
        print("      0 !NGRP", file=f)
        print(file=f)


Instruction:
Can you implement a function in Python 3 that
adds the molecular graph of the given molecule to the data structure

Response:
def add_molecule(self, molecule, atom_types=None, charges=None, split=True):
        """Add the graph of the molecule to the data structure

           The molecular graph is estimated from the molecular geometry based on
           interatomic distances.

           Argument:
            | ``molecule``  --  a Molecule instance

           Optional arguments:
            | ``atom_types``  --  a list with atom type strings
            | ``charges``  --  The net atom charges
            | ``split``  --  When True, the molecule is split into disconnected
                             molecules [default=True]
        """
        molecular_graph = MolecularGraph.from_geometry(molecule)
        self.add_molecular_graph(molecular_graph, atom_types, charges, split, molecule)


Instruction:
How would you explain what the following Python 3 function does
def add_molecular_graph(self, molecular_graph, atom_types=None, charges=None, split=True, molecule=None):
        # add atom numbers and molecule indices
        new = len(molecular_graph.numbers)
        if new == 0: return
        prev = len(self.numbers)
        offset = prev
        self.numbers.resize(prev + new)
        self.numbers[-new:] = molecular_graph.numbers
        if atom_types is None:
            atom_types = [periodic[number].symbol for number in molecular_graph.numbers]
        self.atom_types.extend(atom_types)
        if charges is None:
            charges = [0.0]*len(molecular_graph.numbers)
        self.charges.extend(charges)
        self.molecules.resize(prev + new)

        # add names (autogenerated)
        if split:
            groups = molecular_graph.independent_vertices
            names = [self._get_name(molecular_graph, group) for group in groups]
            group_indices = np.zeros(new, int)
            for group_index, group in enumerate(groups):
                for index in group:
                    group_indices[index] = group_index
            self.names.extend([names[group_index] for group_index in group_indices])
            if prev == 0:
                self.molecules[:] = group_indices
            else:
                self.molecules[-new:] = self.molecules[-new]+group_indices+1
        else:
            if prev == 0:
                self.molecules[-new:] = 0
            else:
                self.molecules[-new:] = self.molecules[-new]+1
            name = self._get_name(molecular_graph)
            self.names.extend([name]*new)

        self._add_graph_bonds(molecular_graph, offset, atom_types, molecule)
        self._add_graph_bends(molecular_graph, offset, atom_types, molecule)
        self._add_graph_dihedrals(molecular_graph, offset, atom_types, molecule)
        self._add_graph_impropers(molecular_graph, offset, atom_types, molecule)

Response: Adds the molecular graph to the data structure


Instruction:
Write a Python 3 script for
returning a list of groups of atom indexes Each atom in a group belongs to the same molecule or residue.

Response:
def get_groups(self):
        """Return a list of groups of atom indexes

           Each atom in a group belongs to the same molecule or residue.
        """
        groups = []
        for a_index, m_index in enumerate(self.molecules):
            if m_index >= len(groups):
                groups.append([a_index])
            else:
                groups[m_index].append(a_index)
        return groups


Instruction:
Here you have a function in Python 3, explain what it does
def iter_halfs_bond(graph):
    for atom1, atom2 in graph.edges:
        try:
            affected_atoms1, affected_atoms2 = graph.get_halfs(atom1, atom2)
            yield affected_atoms1, affected_atoms2, (atom1, atom2)
        except GraphError:
            # just try again
            continue

Response: Iterate over the bonds that divides the molecule in two


Instruction:
How would you implement a function in Python 3 that
iterates over the bonds that divide the molecule in two

Response:
def iter_halfs_bend(graph):
    """Select randomly two consecutive bonds that divide the molecule in two"""
    for atom2 in range(graph.num_vertices):
        neighbors = list(graph.neighbors[atom2])
        for index1, atom1 in enumerate(neighbors):
            for atom3 in neighbors[index1+1:]:
                try:
                    affected_atoms = graph.get_halfs(atom2, atom1)[0]
                    # the affected atoms never contain atom1!
                    yield affected_atoms, (atom1, atom2, atom3)
                    continue
                except GraphError:
                    pass
                try:
                    affected_atoms = graph.get_halfs(atom2, atom3)[0]
                    # the affected atoms never contain atom3!
                    yield affected_atoms, (atom3, atom2, atom1)
                except GraphError:
                    pass


Instruction:
Can you generate a brief explanation for the following Python 3 code
def iter_halfs_double(graph):
    edges = graph.edges
    for index1, (atom_a1, atom_b1) in enumerate(edges):
        for atom_a2, atom_b2 in edges[:index1]:
            try:
                affected_atoms1, affected_atoms2, hinge_atoms = graph.get_halfs_double(atom_a1, atom_b1, atom_a2, atom_b2)
                yield affected_atoms1, affected_atoms2, hinge_atoms
            except GraphError:
                pass

Response: Iterate over the two random non - consecutive bonds that divide the molecule in two


Instruction:
How would you explain what the following Python 3 function does
def generate_manipulations(
    molecule, bond_stretch_factor=0.15, torsion_amplitude=np.pi,
    bending_amplitude=0.30
):
    """Generate a (complete) set of manipulations

       The result can be used as input for the functions 'randomize_molecule'
       and 'single_random_manipulation'

       Arguments:
         molecule  --  a reference geometry of the molecule, with graph
                       attribute
         bond_stretch_factor  --  the maximum relative change in bond length by
                                  one bond stretch manipulatio
         torsion_amplitude  --  the maximum change a dihdral angle
         bending_amplitude  --  the maximum change in a bending angle

       The return value is a list of RandomManipulation objects. They can be
       used to generate different random distortions of the original molecule.
    """
    do_stretch = (bond_stretch_factor > 0)
    do_double_stretch = (bond_stretch_factor > 0)
    do_bend = (bending_amplitude > 0)
    do_double_bend = (bending_amplitude > 0)
    do_torsion = (torsion_amplitude > 0)

    results = []
    # A) all manipulations that require one bond that cuts the molecule in half
    if do_stretch or do_torsion:
        for affected_atoms1, affected_atoms2, hinge_atoms in iter_halfs_bond(molecule.graph):
            if do_stretch:
                length = np.linalg.norm(
                    molecule.coordinates[hinge_atoms[0]] -
                    molecule.coordinates[hinge_atoms[1]]
                )
                results.append(RandomStretch(
                    affected_atoms1, length*bond_stretch_factor, hinge_atoms
                ))
            if do_torsion and len(affected_atoms1) > 1 and len(affected_atoms2) > 1:
                results.append(RandomTorsion(
                    affected_atoms1, torsion_amplitude, hinge_atoms
                ))
    # B) all manipulations that require a bending angle that cuts the molecule
    #    in two parts
    if do_bend:
        for affected_atoms, hinge_atoms in iter_halfs_bend(molecule.graph):
            results.append(RandomBend(
                affected_atoms, bending_amplitude, hinge_atoms
            ))
    # C) all manipulations that require two bonds that separate two halfs
    if do_double_stretch or do_double_bend:
        for affected_atoms1, affected_atoms2, hinge_atoms in iter_halfs_double(molecule.graph):
            if do_double_stretch:
                length1 = np.linalg.norm(
                    molecule.coordinates[hinge_atoms[0]] -
                    molecule.coordinates[hinge_atoms[1]]
                )
                length2 = np.linalg.norm(
                    molecule.coordinates[hinge_atoms[2]] -
                    molecule.coordinates[hinge_atoms[3]]
                )
                results.append(RandomDoubleStretch(
                    affected_atoms1, 0.5*(length1+length2)*bond_stretch_factor, hinge_atoms
                ))
            if do_double_bend and len(affected_atoms1) > 2 and len(affected_atoms2) > 2:
                if hinge_atoms[0] != hinge_atoms[2]:
                    results.append(RandomTorsion(
                        affected_atoms1, bending_amplitude, (hinge_atoms[0], hinge_atoms[2])
                    ))
                if hinge_atoms[1] != hinge_atoms[3]:
                    results.append(RandomTorsion(
                        affected_atoms2, bending_amplitude, (hinge_atoms[1], hinge_atoms[3])
                    ))
    # Neglect situations where three or more cuts are required.
    return results

Response: Generates a set of random manipulations for a single molecule.


Instruction:
Can you generate the documentation for the following Python 3 function
def check_nonbond(molecule, thresholds):

    # check that no atoms overlap
    for atom1 in range(molecule.graph.num_vertices):
        for atom2 in range(atom1):
            if molecule.graph.distances[atom1, atom2] > 2:
                distance = np.linalg.norm(molecule.coordinates[atom1] - molecule.coordinates[atom2])
                if distance < thresholds[frozenset([molecule.numbers[atom1], molecule.numbers[atom2]])]:
                    return False
    return True

Response: Checks whether all nonbonded atoms are well separated and if they are not then returns False.


Instruction:
How would you code a function in Python 3 to
return a randomized copy of the molecule.

Response:
def randomize_molecule(molecule, manipulations, nonbond_thresholds, max_tries=1000):
    """Return a randomized copy of the molecule.

       If no randomized molecule can be generated that survives the nonbond
       check after max_tries repetitions, None is returned. In case of success,
       the randomized molecule is returned. The original molecule is not
       altered.
    """
    for m in range(max_tries):
        random_molecule = randomize_molecule_low(molecule, manipulations)
        if check_nonbond(random_molecule, nonbond_thresholds):
            return random_molecule


Instruction:
Can you generate a brief explanation for the following Python 3 code
def randomize_molecule_low(molecule, manipulations):

    manipulations = copy.copy(manipulations)
    shuffle(manipulations)
    coordinates = molecule.coordinates.copy()
    for manipulation in manipulations:
        manipulation.apply(coordinates)
    return molecule.copy_with(coordinates=coordinates)

Response: Return a randomized copy of the molecule with the nonbond check applied.


Instruction:
Implement a Python 3 function for
applying a single random manipulation.

Response:
def single_random_manipulation(molecule, manipulations, nonbond_thresholds, max_tries=1000):
    """Apply a single random manipulation.

       If no randomized molecule can be generated that survives the nonbond
       check after max_tries repetitions, None is returned. In case of success,
       the randomized molecule and the corresponding transformation is returned.
       The original molecule is not altered.
    """
    for m in range(max_tries):
        random_molecule, transformation = single_random_manipulation_low(molecule, manipulations)
        if check_nonbond(random_molecule, nonbond_thresholds):
            return random_molecule, transformation
    return None


Instruction:
Here you have a function in Python 3, explain what it does
def single_random_manipulation_low(molecule, manipulations):

    manipulation = sample(manipulations, 1)[0]
    coordinates = molecule.coordinates.copy()
    transformation = manipulation.apply(coordinates)
    return molecule.copy_with(coordinates=coordinates), transformation

Response: Return a randomized copy of the molecule without the nonbond check.


Instruction:
Write a Python 3 script for
creating a random dimer that can be used to create a random molecule.

Response:
def random_dimer(molecule0, molecule1, thresholds, shoot_max):
    """Create a random dimer.

       molecule0 and molecule1 are placed in one reference frame at random
       relative positions. Interatomic distances are above the thresholds.
       Initially a dimer is created where one interatomic distance approximates
       the threshold value. Then the molecules are given an additional
       separation in the range [0, shoot_max].

       thresholds has the following format:
       {frozenset([atom_number1, atom_number2]): distance}
    """

    # apply a random rotation to molecule1
    center = np.zeros(3, float)
    angle = np.random.uniform(0, 2*np.pi)
    axis = random_unit()
    rotation = Complete.about_axis(center, angle, axis)
    cor1 = np.dot(molecule1.coordinates, rotation.r)

    # select a random atom in each molecule
    atom0 = np.random.randint(len(molecule0.numbers))
    atom1 = np.random.randint(len(molecule1.numbers))

    # define a translation of molecule1 that brings both atoms in overlap
    delta = molecule0.coordinates[atom0] - cor1[atom1]
    cor1 += delta

    # define a random direction
    direction = random_unit()
    cor1 += 1*direction

    # move molecule1 along this direction until all intermolecular atomic
    # distances are above the threshold values
    threshold_mat = np.zeros((len(molecule0.numbers), len(molecule1.numbers)), float)
    distance_mat = np.zeros((len(molecule0.numbers), len(molecule1.numbers)), float)
    for i1, n1 in enumerate(molecule0.numbers):
        for i2, n2 in enumerate(molecule1.numbers):
            threshold = thresholds.get(frozenset([n1, n2]))
            threshold_mat[i1, i2] = threshold**2
    while True:
        cor1 += 0.1*direction
        distance_mat[:] = 0
        for i in 0, 1, 2:
            distance_mat += np.subtract.outer(molecule0.coordinates[:, i], cor1[:, i])**2
        if (distance_mat > threshold_mat).all():
            break

    # translate over a random distance [0, shoot] along the same direction
    # (if necessary repeat until no overlap is found)
    while True:
        cor1 += direction*np.random.uniform(0, shoot_max)
        distance_mat[:] = 0
        for i in 0, 1, 2:
            distance_mat += np.subtract.outer(molecule0.coordinates[:, i], cor1[:, i])**2
        if (distance_mat > threshold_mat).all():
            break

    # done
    dimer = Molecule(
        np.concatenate([molecule0.numbers, molecule1.numbers]),
        np.concatenate([molecule0.coordinates, cor1])
    )
    dimer.direction = direction
    dimer.atom0 = atom0
    dimer.atom1 = atom1
    return dimer


Instruction:
Can you generate the documentation for the following Python 3 function
def read_from_file(cls, filename):
        with open(filename) as f:
            lines = list(line for line in f if line[0] != '#')
        r = []
        t = []
        for line in lines[:3]:
            values = list(float(word) for word in line.split())
            r.append(values[:3])
            t.append(values[3])
        transformation = Complete(r, t)
        affected_atoms = set(int(word) for word in lines[3].split())
        return cls(affected_atoms, transformation)

Response: Construct a MolecularDistortion object from a file


Instruction:
Write a Python 3 function for
applying this distortion to Cartesian coordinates

Response:
def apply(self, coordinates):
        """Apply this distortion to Cartesian coordinates"""
        for i in self.affected_atoms:
            coordinates[i] = self.transformation*coordinates[i]


Instruction:
Write a Python 3 function for
writing the object to a file

Response:
def write_to_file(self, filename):
        """Write the object to a file"""
        r = self.transformation.r
        t = self.transformation.t
        with open(filename, "w") as f:
            print("# A (random) transformation of a part of a molecule:", file=f)
            print("# The translation vector is in atomic units.", file=f)
            print("#     Rx             Ry             Rz              T", file=f)
            print("% 15.9e % 15.9e % 15.9e % 15.9e" % (r[0, 0], r[0, 1], r[0, 2], t[0]), file=f)
            print("% 15.9e % 15.9e % 15.9e % 15.9e" % (r[1, 0], r[1, 1], r[1, 2], t[1]), file=f)
            print("% 15.9e % 15.9e % 15.9e % 15.9e" % (r[2, 0], r[2, 1], r[2, 2], t[2]), file=f)
            print("# The indexes of the affected atoms:", file=f)
            print(" ".join(str(i) for i in self.affected_atoms), file=f)


Instruction:
Here you have a function in Python 3, explain what it does
def apply(self, coordinates):
        transform = self.get_transformation(coordinates)
        result = MolecularDistortion(self.affected_atoms, transform)
        result.apply(coordinates)
        return result

Response: Generate apply and return a random manipulation


Instruction:
Can you generate a brief explanation for the following Python 3 code
def get_transformation(self, coordinates):
        atom1, atom2 = self.hinge_atoms
        direction = coordinates[atom1] - coordinates[atom2]
        direction /= np.linalg.norm(direction)
        direction *= np.random.uniform(-self.max_amplitude, self.max_amplitude)
        result = Translation(direction)
        return result

Response: Construct a translation object from the given coordinates


Instruction:
Can you tell what is the following Python 3 function doing
def get_transformation(self, coordinates):
        atom1, atom2 = self.hinge_atoms
        center = coordinates[atom1]
        axis = coordinates[atom1] - coordinates[atom2]
        axis /= np.linalg.norm(axis)
        angle = np.random.uniform(-self.max_amplitude, self.max_amplitude)
        return Complete.about_axis(center, angle, axis)

Response: Construct a transformation object from the given coordinates.


Instruction:
How would you explain what the following Python 3 function does
def get_transformation(self, coordinates):
        atom1, atom2, atom3 = self.hinge_atoms
        center = coordinates[atom2]
        a = coordinates[atom1] - coordinates[atom2]
        b = coordinates[atom3] - coordinates[atom2]
        axis = np.cross(a, b)
        norm = np.linalg.norm(axis)
        if norm < 1e-5:
            # We suppose that atom3 is part of the affected atoms
            axis = random_orthonormal(a)
        else:
            axis /= np.linalg.norm(axis)
        angle = np.random.uniform(-self.max_amplitude, self.max_amplitude)
        return Complete.about_axis(center, angle, axis)

Response: Construct a transformation object from the given coordinates.


Instruction:
Implement a function in Python 3 to
construct a translation object from the given coordinates

Response:
def get_transformation(self, coordinates):
        """Construct a transformation object"""
        atom1, atom2, atom3, atom4 = self.hinge_atoms
        a = coordinates[atom1] - coordinates[atom2]
        a /= np.linalg.norm(a)
        b = coordinates[atom3] - coordinates[atom4]
        b /= np.linalg.norm(b)
        direction = 0.5*(a+b)
        direction *= np.random.uniform(-self.max_amplitude, self.max_amplitude)
        result = Translation(direction)
        return result


Instruction:
Write a Python 3 function that can
iterate over all bins surrounding the given center key

Response:
def iter_surrounding(self, center_key):
        """Iterate over all bins surrounding the given bin"""
        for shift in self.neighbor_indexes:
            key = tuple(np.add(center_key, shift).astype(int))
            if self.integer_cell is not None:
                key = self.wrap_key(key)
            bin = self._bins.get(key)
            if bin is not None:
                yield key, bin


Instruction:
Make a summary of the following Python 3 code
def wrap_key(self, key):
        return tuple(np.round(
            self.integer_cell.shortest_vector(key)
        ).astype(int))

Response: Translate the key into the central cell


Instruction:
Create a Python 3 function for
choosing a proper grid for the binning process

Response:
def _setup_grid(self, cutoff, unit_cell, grid):
        """Choose a proper grid for the binning process"""
        if grid is None:
            # automatically choose a decent grid
            if unit_cell is None:
                grid = cutoff/2.9
            else:
                # The following would be faster, but it is not reliable
                # enough yet.
                #grid = unit_cell.get_optimal_subcell(cutoff/2.0)
                divisions = np.ceil(unit_cell.spacings/cutoff)
                divisions[divisions<1] = 1
                grid = unit_cell/divisions

        if isinstance(grid, float):
            grid_cell = UnitCell(np.array([
                [grid, 0, 0],
                [0, grid, 0],
                [0, 0, grid]
            ]))
        elif isinstance(grid, UnitCell):
            grid_cell = grid
        else:
            raise TypeError("Grid must be None, a float or a UnitCell instance.")

        if unit_cell is not None:
            # The columns of integer_matrix are the unit cell vectors in
            # fractional coordinates of the grid cell.
            integer_matrix = grid_cell.to_fractional(unit_cell.matrix.transpose()).transpose()
            if abs((integer_matrix - np.round(integer_matrix))*self.unit_cell.active).max() > 1e-6:
                raise ValueError("The unit cell vectors are not an integer linear combination of grid cell vectors.")
            integer_matrix = integer_matrix.round()
            integer_cell = UnitCell(integer_matrix, unit_cell.active)
        else:
            integer_cell = None

        return grid_cell, integer_cell


Instruction:
Can you generate a brief explanation for the following Python 3 code
def parse_unit(expression):
    try:
        g = globals()
        g.update(shorthands)
        return float(eval(str(expression), g))
    except:
        raise ValueError("Could not interpret '%s' as a unit or a measure." % expression)

Response:
Evaluate a python expression string containing constants
ATTRIBS and return a float.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def parents(self):
        q = self.__parent__.parents()
        q.put(self)
        return q

Response: Returns a FIFO queue with the ancestors and itself.


Instruction:
Make a summary of the following Python 3 code
def url(self):
        path = None
        nodes = self.parents()
        while not nodes.empty():
            path = urljoin(path, nodes.get().path())
        return path

Response: Returns the whole URL from the base to this node.


Instruction:
Given the following Python 3 function, write the documentation
def auth_required(self):
        if self._auth:
            return self._auth, self
        return self.__parent__.auth_required()

Response: Returns a tuple of the authentication and the parent node if any.


Instruction:
Can you tell what is the following Python 3 function doing
def _check_graph(self, graph):
        if graph.num_vertices != self.size:
            raise TypeError("The number of vertices in the graph does not "
                "match the length of the atomic numbers array.")
        # In practice these are typically the same arrays using the same piece
        # of memory. Just checking to be sure.
        if (self.numbers != graph.numbers).any():
            raise TypeError("The atomic numbers in the graph do not match the "
                "atomic numbers in the molecule.")

Response: Check that the atomic numbers in the graph are consistent with the molecule.


Instruction:
Can you generate the documentation for the following Python 3 function
def from_file(cls, filename):
        # TODO: many different API's to load files. brrr...
        if filename.endswith(".cml"):
            from molmod.io import load_cml
            return load_cml(filename)[0]
        elif filename.endswith(".fchk"):
            from molmod.io import FCHKFile
            fchk = FCHKFile(filename, field_labels=[])
            return fchk.molecule
        elif filename.endswith(".pdb"):
            from molmod.io import load_pdb
            return load_pdb(filename)
        elif filename.endswith(".sdf"):
            from molmod.io import SDFReader
            return next(SDFReader(filename))
        elif filename.endswith(".xyz"):
            from molmod.io import XYZReader
            xyz_reader = XYZReader(filename)
            title, coordinates = next(xyz_reader)
            return Molecule(xyz_reader.numbers, coordinates, title, symbols=xyz_reader.symbols)
        else:
            raise ValueError("Could not determine file format for %s." % filename)

Response: Construct a Molecule object from a file.


Instruction:
Can you generate the documentation for the following Python 3 function
def chemical_formula(self):
        counts = {}
        for number in self.numbers:
            counts[number] = counts.get(number, 0)+1
        items = []
        for number, count in sorted(counts.items(), reverse=True):
            if count == 1:
                items.append(periodic[number].symbol)
            else:
                items.append("%s%i" % (periodic[number].symbol, count))
        return "".join(items)

Response: the chemical formula of the molecule


Instruction:
Can you create a Python 3 function that
sets self. masses based on self. numbers and periodic table.

Response:
def set_default_masses(self):
        """Set self.masses based on self.numbers and periodic table."""
        self.masses = np.array([periodic[n].mass for n in self.numbers])


Instruction:
Can you create a Python 3 function that
sets self. symbols based on self. numbers and the periodic table.

Response:
def set_default_symbols(self):
        """Set self.symbols based on self.numbers and the periodic table."""
        self.symbols = tuple(periodic[n].symbol for n in self.numbers)


Instruction:
Can you tell what is the following Python 3 function doing
def write_to_file(self, filename):
        # TODO: give all file format writers the same API
        if filename.endswith('.cml'):
            from molmod.io import dump_cml
            dump_cml(filename, [self])
        elif filename.endswith('.xyz'):
            from molmod.io import XYZWriter
            symbols = []
            for n in self.numbers:
                atom = periodic[n]
                if atom is None:
                    symbols.append("X")
                else:
                    symbols.append(atom.symbol)
            xyz_writer = XYZWriter(filename, symbols)
            xyz_writer.dump(self.title, self.coordinates)
            del xyz_writer
        else:
            raise ValueError("Could not determine file format for %s." % filename)

Response: Write the molecular geometry to a file.


Instruction:
Create a Python 3 function for
computing the RMSD between two molecules.

Response:
def rmsd(self, other):
        """Compute the RMSD between two molecules.

           Arguments:
            | ``other``  --  Another molecule with the same atom numbers

           Return values:
            | ``transformation``  --  the transformation that brings 'self' into
                                  overlap with 'other'
            | ``other_trans``  --  the transformed coordinates of geometry 'other'
            | ``rmsd``  --  the rmsd of the distances between corresponding atoms in
                            'self' and 'other'

           Make sure the atoms in `self` and `other` are in the same order.

           Usage::

             >>> print molecule1.rmsd(molecule2)[2]/angstrom
        """
        if self.numbers.shape != other.numbers.shape or \
           (self.numbers != other.numbers).all():
            raise ValueError("The other molecule does not have the same numbers as this molecule.")
        return fit_rmsd(self.coordinates, other.coordinates)


Instruction:
Can you implement a function in Python 3 that
computes the rotational symmetry number.

Response:
def compute_rotsym(self, threshold=1e-3*angstrom):
        """Compute the rotational symmetry number.

           Optional argument:
            | ``threshold``  --  only when a rotation results in an rmsd below the given
                                 threshold, the rotation is considered to transform the
                                 molecule onto itself.
        """
        # Generate a graph with a more permissive threshold for bond lengths:
        # (is convenient in case of transition state geometries)
        graph = MolecularGraph.from_geometry(self, scaling=1.5)
        try:
            return compute_rotsym(self, graph, threshold)
        except ValueError:
            raise ValueError("The rotational symmetry number can only be computed when the graph is fully connected.")


Instruction:
How would you code a function in Python 3 to
get the label from the last line read

Response:
def _get_current_label(self):
        """Get the label from the last line read"""
        if len(self._last) == 0:
            raise StopIteration
        return self._last[:self._last.find(":")]


Instruction:
Explain what the following Python 3 code does
def _skip_section(self):
        self._last = self._f.readline()
        while len(self._last) > 0 and len(self._last[0].strip()) == 0:
            self._last = self._f.readline()

Response: Skip a section of the log file.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _read_section(self):
        lines = [self._last[self._last.find(":")+1:]]
        self._last = self._f.readline()
        while len(self._last) > 0 and len(self._last[0].strip()) == 0:
            lines.append(self._last)
            self._last = self._f.readline()
        return lines

Response: Read and return an entire section


Instruction:
Can you tell what is the following Python 3 function doing
def get_next(self, label):
        while self._get_current_label() != label:
            self._skip_section()
        return self._read_section()

Response: Get the next section with the given label


Instruction:
Create a Python 3 function for
reading a single ATRJFrame from the trajectory

Response:
def _read_frame(self):
        """Read a single frame from the trajectory"""
        self._secfile.get_next("Frame Number")
        frame = ATRJFrame()
        # Read the time and energy
        energy_lines = self._secfile.get_next("Time/Energy")
        energy_words = energy_lines[0].split()
        frame.time = float(energy_words[0])*picosecond
        frame.step = int(energy_words[1])
        frame.total_energy = float(energy_words[2])*kcalmol
        # Read the coordinates
        coord_lines = self._secfile.get_next("Coordinates")
        frame.coordinates = np.zeros((self.num_atoms, 3), float)
        for index, line in enumerate(coord_lines):
            words = line.split()
            frame.coordinates[index, 0] = float(words[1])
            frame.coordinates[index, 1] = float(words[2])
            frame.coordinates[index, 2] = float(words[3])
        frame.coordinates *= angstrom
        # Done
        return frame


Instruction:
Write a Python 3 function that can
generate the Cartesian coordinates of the points in a cube file.

Response:
def get_cube_points(origin, axes, nrep):
    '''Generate the Cartesian coordinates of the points in a cube file

       *Arguemnts:*

       origin
            The cartesian coordinate for the origin of the grid.

       axes
            The 3 by 3 array with the grid spacings as rows.

       nrep
            The number of grid points along each axis.
    '''
    points = np.zeros((nrep[0], nrep[1], nrep[2], 3), float)
    points[:] = origin
    points[:] += np.outer(np.arange(nrep[0], dtype=float), axes[0]).reshape((-1,1,1,3))
    points[:] += np.outer(np.arange(nrep[1], dtype=float), axes[1]).reshape((1,-1,1,3))
    points[:] += np.outer(np.arange(nrep[2], dtype=float), axes[2]).reshape((1,1,-1,3))
    return points


Instruction:
Make a summary of the following Python 3 code
def from_file(cls, filename):
        '''Create a cube object by loading data from a file.

           *Arguemnts:*

           filename
                The file to load. It must contain the header with the
                description of the grid and the molecule.
        '''
        with open(filename) as f:
            molecule, origin, axes, nrep, subtitle, nuclear_charges = \
                read_cube_header(f)
            data = np.zeros(tuple(nrep), float)
            tmp = data.ravel()
            counter = 0
            while True:
                line = f.readline()
                if len(line) == 0:
                    break
                words = line.split()
                for word in words:
                    tmp[counter] = float(word)
                    counter += 1
        return cls(molecule, origin, axes, nrep, data, subtitle, nuclear_charges)

Response: Create a cube object by loading data from a file.


Instruction:
Write a Python 3 function that can
write the cube to a file in the Gaussian cube format.

Response:
def write_to_file(self, fn):
        '''Write the cube to a file in the Gaussian cube format.'''
        with open(fn, 'w') as f:
            f.write(' {}\n'.format(self.molecule.title))
            f.write(' {}\n'.format(self.subtitle))

            def write_grid_line(n, v):
                f.write('%5i % 11.6f % 11.6f % 11.6f\n' % (n, v[0], v[1], v[2]))

            write_grid_line(self.molecule.size, self.origin)
            write_grid_line(self.data.shape[0], self.axes[0])
            write_grid_line(self.data.shape[1], self.axes[1])
            write_grid_line(self.data.shape[2], self.axes[2])

            def write_atom_line(n, nc, v):
                f.write('%5i % 11.6f % 11.6f % 11.6f % 11.6f\n' % (n, nc, v[0], v[1], v[2]))

            for i in range(self.molecule.size):
                write_atom_line(self.molecule.numbers[i], self.nuclear_charges[i],
                                self.molecule.coordinates[i])

            for i0 in range(self.data.shape[0]):
                for i1 in range(self.data.shape[1]):
                    col = 0
                    for i2 in range(self.data.shape[2]):
                        value = self.data[i0, i1, i2]
                        if col % 6 == 5:
                            f.write(' % 12.5e\n' % value)
                        else:
                            f.write(' % 12.5e' % value)
                        col += 1
                    if col % 6 != 5:
                        f.write('\n')


Instruction:
Make a summary of the following Python 3 code
def copy(self, newdata=None):
        '''Return a copy of the cube with optionally new data.'''
        if newdata is None:
            newdata = self.data.copy()
        return self.__class__(
            self.molecule, self.origin.copy(), self.axes.copy(),
            self.nrep.copy(), newdata, self.subtitle, self.nuclear_charges
        )

Response: Return a copy of the cube with optionally new data.


Instruction:
Implement a function in Python 3 to
check the constency between self. __index and self. order

Response:
def _consistent(self):
        """Checks the constency between self.__index and self.__order"""
        if len(self.__order) != sum(len(values) for values in self.__index.values()):
            return False
        import copy
        tmp = copy.copy(self.__order)
        for key, values in self.__index.items():
            for value in values:
                if value.name != key:
                    return False
                if value in tmp:
                    tmp.remove(value)
                else:
                    return False
                if isinstance(value, CP2KSection):
                    if not value._consistent():
                        return False
        return True


Instruction:
Write a Python 3 function for
adding a child section or keyword to the end of the list.

Response:
def append(self, child):
        """Add a child section or keyword"""
        if not (isinstance(child, CP2KSection) or isinstance(child, CP2KKeyword)):
            raise TypeError("The child must be a CP2KSection or a CP2KKeyword, got: %s." % child)
        l = self.__index.setdefault(child.name, [])
        l.append(child)
        self.__order.append(child)


Instruction:
Explain what the following Python 3 code does
def dump_children(self, f, indent=''):
        for child in self.__order:
            child.dump(f, indent+'  ')

Response: Dump the children of the current section to a file - like object


Instruction:
How would you code a function in Python 3 to
dump this section and its children to a file - like object

Response:
def dump(self, f, indent=''):
        """Dump this section and its children to a file-like object"""
        print(("%s&%s %s" % (indent, self.__name, self.section_parameters)).rstrip(), file=f)
        self.dump_children(f, indent)
        print("%s&END %s" % (indent, self.__name), file=f)


Instruction:
Can you generate the documentation for the following Python 3 function
def readline(self, f):
        while True:
            line = f.readline()
            if len(line) == 0:
                raise EOFError
            line = line[:line.find('#')]
            line = line.strip()
            if len(line) > 0:
                return line

Response: A helper method that only reads uncommented lines


Instruction:
Implement a function in Python 3 to
load the children of this section from a file - like object

Response:
def load_children(self, f):
        """Load the children of this section from a file-like object"""
        while True:
            line = self.readline(f)
            if line[0] == '&':
                if line[1:].startswith("END"):
                    check_name = line[4:].strip().upper()
                    if check_name != self.__name:
                        raise FileFormatError("CP2KSection end mismatch, pos=%s", f.tell())
                    break
                else:
                    section = CP2KSection()
                    section.load(f, line)
                    self.append(section)
            else:
                keyword = CP2KKeyword()
                keyword.load(line)
                self.append(keyword)


Instruction:
Can you write a function in Python 3 where it
loads this section from a file - like object

Response:
def load(self, f, line=None):
        """Load this section from a file-like object"""
        if line is None:
            # in case the file contains only a fragment of an input file,
            # this is useful.
            line = f.readlin()
        words = line[1:].split()
        self.__name = words[0].upper()
        self.section_parameters = " ".join(words[1:])
        try:
            self.load_children(f)
        except EOFError:
            raise FileFormatError("Unexpected end of file, section '%s' not ended." % self.__name)


Instruction:
Implement a Python 3 function for
dumping this keyword to a file - like object

Response:
def dump(self, f, indent=''):
        """Dump this keyword to a file-like object"""
        if self.__unit is None:
            print(("%s%s %s" % (indent, self.__name, self.__value)).rstrip(), file=f)
        else:
            print(("%s%s [%s] %s" % (indent, self.__name, self.__unit, self.__value)).rstrip(), file=f)


Instruction:
Create a Python 3 function for
loading this keyword from a file - like object

Response:
def load(self, line):
        """Load this keyword from a file-like object"""
        words = line.split()
        try:
            float(words[0])
            self.__name = ""
            self.__value = " ".join(words)
        except ValueError:
            self.__name = words[0].upper()
            if len(words) > 2 and words[1][0]=="[" and words[1][-1]=="]":
                self.unit = words[1][1:-1]
                self.__value = " ".join(words[2:])
            else:
                self.__value = " ".join(words[1:])


Instruction:
Can you tell what is the following Python 3 function doing
def set_value(self, value):
        if not isinstance(value, str):
            raise TypeError("A value must be a string, got %s." % value)
        self.__value = value

Response: Set the value associated with the keyword


Instruction:
How would you explain what the following Python 3 function does
def read_from_file(filename):
        with open(filename) as f:
            result = CP2KInputFile()
            try:
                while True:
                    result.load_children(f)
            except EOFError:
                pass
        return result

Response: Reads a file containing the contents of the file.


Instruction:
Implement a Python 3 function for
reading and return the next time frame

Response:
def _read_frame(self):
        """Read and return the next time frame"""
        pos = np.zeros((self.num_atoms, 3), float)
        vel = np.zeros((self.num_atoms, 3), float)
        for i in range(self.num_atoms):
            line = next(self._f)
            words = line.split()
            pos[i, 0] = float(words[1])
            pos[i, 1] = float(words[2])
            pos[i, 2] = float(words[3])
            vel[i, 0] = float(words[4])
            vel[i, 1] = float(words[5])
            vel[i, 2] = float(words[6])
        return pos, vel


Instruction:
Implement a function in Python 3 to
check the sanity of the given 4x4 transformation matrix

Response:
def check_matrix(m):
    """Check the sanity of the given 4x4 transformation matrix"""
    if m.shape != (4, 4):
        raise ValueError("The argument must be a 4x4 array.")
    if max(abs(m[3, 0:3])) > eps:
        raise ValueError("The given matrix does not have correct translational part")
    if abs(m[3, 3] - 1.0) > eps:
        raise ValueError("The lower right element of the given matrix must be 1.0.")


Instruction:
Create a Python 3 function for
computing the transformation that minimizes the RMSD between the points ras and rbs.

Response:
def superpose(ras, rbs, weights=None):
    """Compute the transformation that minimizes the RMSD between the points ras and rbs

       Arguments:
        | ``ras``  --  a ``np.array`` with 3D coordinates of geometry A,
                       shape=(N,3)
        | ``rbs``  --  a ``np.array`` with 3D coordinates of geometry B,
                       shape=(N,3)

       Optional arguments:
        | ``weights``  --  a numpy array with fitting weights for each
                           coordinate, shape=(N,)

       Return value:
        | ``transformation``  --  the transformation that brings geometry A into
                                  overlap with geometry B

       Each row in ras and rbs represents a 3D coordinate. Corresponding rows
       contain the points that are brought into overlap by the fitting
       procedure. The implementation is based on the Kabsch Algorithm:

       http://dx.doi.org/10.1107%2FS0567739476001873
    """
    if weights is None:
        ma = ras.mean(axis=0)
        mb = rbs.mean(axis=0)
    else:
        total_weight = weights.sum()
        ma = np.dot(weights, ras)/total_weight
        mb = np.dot(weights, rbs)/total_weight

    # Kabsch
    if weights is None:
        A = np.dot((rbs-mb).transpose(), ras-ma)
    else:
        weights = weights.reshape((-1, 1))
        A = np.dot(((rbs-mb)*weights).transpose(), (ras-ma)*weights)
    v, s, wt = np.linalg.svd(A)
    s[:] = 1
    if np.linalg.det(np.dot(v, wt)) < 0:
        s[2] = -1
    r = np.dot(wt.T*s, v.T)
    return Complete(r, np.dot(r, -mb) + ma)


Instruction:
Implement a Python 3 function for
applying this translation to the given object x.

Response:
def apply_to(self, x, columns=False):
        """Apply this translation to the given object

           The argument can be several sorts of objects:

           * ``np.array`` with shape (3, )
           * ``np.array`` with shape (N, 3)
           * ``np.array`` with shape (3, N), use ``columns=True``
           * ``Translation``
           * ``Rotation``
           * ``Complete``
           * ``UnitCell``

           In case of arrays, the 3D vectors are translated. In case of trans-
           formations, a new transformation is returned that consists of this
           translation applied AFTER the given translation. In case of a unit
           cell, the original object is returned.

           This method is equivalent to ``self*x``.
        """
        if isinstance(x, np.ndarray) and len(x.shape) == 2 and x.shape[0] == 3 and columns:
            return x + self.t.reshape((3,1))
        if isinstance(x, np.ndarray) and (x.shape == (3, ) or (len(x.shape) == 2 and x.shape[1] == 3)) and not columns:
            return x + self.t
        elif isinstance(x, Complete):
            return Complete(x.r, x.t + self.t)
        elif isinstance(x, Translation):
            return Translation(x.t + self.t)
        elif isinstance(x, Rotation):
            return Complete(x.r, self.t)
        elif isinstance(x, UnitCell):
            return x
        else:
            raise ValueError("Can not apply this translation to %s" % x)


Instruction:
Explain what the following Python 3 code does
def compare(self, other, t_threshold=1e-3):
        return compute_rmsd(self.t, other.t) < t_threshold

Response:
Compare two translations

           The RMSD of the translation vectors is computed. The return value
           is True when the RMSD is below the threshold, i.e. when the two
           translations are almost identical.


Instruction:
Can you tell what is the following Python 3 function doing
def _check_r(self, r):
        if abs(np.dot(r[:, 0], r[:, 0]) - 1) > eps or \
            abs(np.dot(r[:, 0], r[:, 0]) - 1) > eps or \
            abs(np.dot(r[:, 0], r[:, 0]) - 1) > eps or \
            np.dot(r[:, 0], r[:, 1]) > eps or \
            np.dot(r[:, 1], r[:, 2]) > eps or \
            np.dot(r[:, 2], r[:, 0]) > eps:
            raise ValueError("The rotation matrix is significantly non-orthonormal.")

Response: check that the columns must orthogonal


Instruction:
How would you explain what the following Python 3 function does
def random(cls):
        axis = random_unit()
        angle = np.random.uniform(0,2*np.pi)
        invert = bool(np.random.randint(0,2))
        return Rotation.from_properties(angle, axis, invert)

Response: Return a random rotation


Instruction:
Implement a Python 3 function for
initializing a rotation based on the properties

Response:
def from_properties(cls, angle, axis, invert):
        """Initialize a rotation based on the properties"""
        norm = np.linalg.norm(axis)
        if norm > 0:
            x = axis[0] / norm
            y = axis[1] / norm
            z = axis[2] / norm
            c = np.cos(angle)
            s = np.sin(angle)
            r = (1-2*invert) * np.array([
                [x*x*(1-c)+c  , x*y*(1-c)-z*s, x*z*(1-c)+y*s],
                [x*y*(1-c)+z*s, y*y*(1-c)+c  , y*z*(1-c)-x*s],
                [x*z*(1-c)-y*s, y*z*(1-c)+x*s, z*z*(1-c)+c  ]
            ])
        else:
            r = np.identity(3) * (1-2*invert)
        return cls(r)


Instruction:
Make a summary of the following Python 3 code
def properties(self):
        # determine wether an inversion rotation has been applied
        invert = (np.linalg.det(self.r) < 0)
        factor = {True: -1, False: 1}[invert]
        # get the rotation data
        # trace(r) = 1+2*cos(angle)
        cos_angle = 0.5*(factor*np.trace(self.r) - 1)
        if cos_angle > 1: cos_angle = 1.0
        if cos_angle < -1: cos_angle = -1.0
        # the antisymmetric part of the non-diagonal vector tell us something
        # about sin(angle) and n.
        axis = 0.5*factor*np.array([-self.r[1, 2] + self.r[2, 1], self.r[0, 2] - self.r[2, 0], -self.r[0, 1] + self.r[1, 0]])
        sin_angle = np.linalg.norm(axis)
        # look for the best way to normalize the
        if (sin_angle == 0.0) and (cos_angle > 0):
            axis[2] = 1.0
        elif abs(sin_angle) < (1-cos_angle):
            for index in range(3):
                axis[index] = {True: -1, False: 1}[axis[index] < 0] * np.sqrt(abs((factor*self.r[index, index] - cos_angle) / (1 - cos_angle)))
        else:
            axis = axis / sin_angle

        # Finally calculate the angle:
        angle = np.arctan2(sin_angle, cos_angle)
        return angle, axis, invert

Response: Rotation properties for the current object


Instruction:
Explain what the following Python 3 code does
def matrix(self):
        result = np.identity(4, float)
        result[0:3, 0:3] = self.r
        return result

Response: The 4x4 matrix representation of this rotation


Instruction:
Explain what the following Python 3 code does
def inv(self):
        result = Rotation(self.r.transpose())
        result._cache_inv = self
        return result

Response: The inverse rotation of the current object


Instruction:
Can you tell what is the following Python 3 function doing
def apply_to(self, x, columns=False):
        if isinstance(x, np.ndarray) and len(x.shape) == 2 and x.shape[0] == 3 and columns:
            return np.dot(self.r, x)
        if isinstance(x, np.ndarray) and (x.shape == (3, ) or (len(x.shape) == 2 and x.shape[1] == 3)) and not columns:
            return np.dot(x, self.r.transpose())
        elif isinstance(x, Complete):
            return Complete(np.dot(self.r, x.r), np.dot(self.r, x.t))
        elif isinstance(x, Translation):
            return Complete(self.r, np.dot(self.r, x.t))
        elif isinstance(x, Rotation):
            return Rotation(np.dot(self.r, x.r))
        elif isinstance(x, UnitCell):
            return UnitCell(np.dot(self.r, x.matrix), x.active)
        else:
            raise ValueError("Can not apply this rotation to %s" % x)

Response: Apply this rotation to the given object x.


Instruction:
Can you tell what is the following Python 3 function doing
def compare(self, other, r_threshold=1e-3):
        return compute_rmsd(self.r, other.r) < r_threshold

Response: Compare two rotations returning True if the RMSD of the rotation matrices is below the threshold.


Instruction:
Can you tell what is the following Python 3 function doing
def from_properties(cls, angle, axis, invert, translation):
        rot = Rotation.from_properties(angle, axis, invert)
        return Complete(rot.r, translation)

Response: Initialize a transformation based on the properties


Instruction:
Explain what the following Python 3 code does
def cast(cls, c):
        if isinstance(c, Complete):
            return c
        elif isinstance(c, Translation):
            return Complete(np.identity(3, float), c.t)
        elif isinstance(c, Rotation):
            return Complete(c.r, np.zeros(3, float))

Response: Convert the first argument into a Complete object


Instruction:
Here you have a function in Python 3, explain what it does
def about_axis(cls, center, angle, axis, invert=False):
        return Translation(center) * \
               Rotation.from_properties(angle, axis, invert) * \
               Translation(-center)

Response: Create transformation that represents a rotation about an axis


Instruction:
Explain what the following Python 3 code does
def compare(self, other, t_threshold=1e-3, r_threshold=1e-3):
        return compute_rmsd(self.t, other.t) < t_threshold and compute_rmsd(self.r, other.r) < r_threshold

Response:
Compare two transformations

           The RMSD values of the rotation matrices and the translation vectors
           are computed. The return value is True when the RMSD values are below
           the thresholds, i.e. when the two transformations are almost
           identical.


Instruction:
Create a Python 3 function to
read and return the next time frame.

Response:
def _read_frame(self):
        """Read and return the next time frame"""
        # Read one frame, we assume that the current file position is at the
        # line 'ITEM: TIMESTEP' and that this line marks the beginning of a
        # time frame.
        line = next(self._f)
        if line != 'ITEM: TIMESTEP\n':
            raise FileFormatError("Expecting line 'ITEM: TIMESTEP' at the beginning of a time frame.")
        try:
            line = next(self._f)
            step = int(line)
        except ValueError:
            raise FileFormatError("Could not read the step number. Expected an integer. Got '%s'" % line[:-1])

        # Now we assume that the next section contains (again) the number of
        # atoms.
        line = next(self._f)
        if line != 'ITEM: NUMBER OF ATOMS\n':
            raise FileFormatError("Expecting line 'ITEM: NUMBER OF ATOMS'.")
        try:
            line = next(self._f)
            num_atoms = int(line)
        except ValueError:
            raise FileFormatError("Could not read the number of atoms. Expected an integer. Got '%s'" % line[:-1])
        if num_atoms != self.num_atoms:
            raise FileFormatError("A variable number of atoms is not supported.")

        # The next section contains the box boundaries. We will skip it
        for i in range(4):
            next(self._f)

        # The next and last section contains the atom related properties
        line = next(self._f)
        if line != 'ITEM: ATOMS\n':
            raise FileFormatError("Expecting line 'ITEM: ATOMS'.")
        fields = [list() for i in range(len(self.units))]
        for i in range(self.num_atoms):
            line = next(self._f)
            words = line.split()[1:]
            for j in range(len(fields)):
                fields[j].append(float(words[j]))
        fields = [step] + [np.array(field)*unit for field, unit in zip(fields, self.units)]

        return fields


Instruction:
How would you code a function in Python 3 to
skip the next time frame

Response:
def _skip_frame(self):
        """Skip the next time frame"""
        for line in self._f:
            if line == 'ITEM: ATOMS\n':
                break
        for i in range(self.num_atoms):
            next(self._f)


Instruction:
Can you implement a function in Python 3 that
adds an atom info object to the database

Response:
def _add_atom_info(self, atom_info):
        """Add an atom info object to the database"""
        self.atoms_by_number[atom_info.number] = atom_info
        self.atoms_by_symbol[atom_info.symbol.lower()] = atom_info


Instruction:
Write a Python 3 script to
extend the current cluster with data from another cluster

Response:
def update(self, other):
        """Extend the current cluster with data from another cluster"""
        Cluster.update(self, other)
        self.rules.extend(other.rules)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def add_related(self, *objects):
        master = None # this will become the common cluster of all related items
        slaves = set([]) # set of clusters that are going to be merged in the master
        solitaire = set([]) # set of new items that are not yet part of a cluster
        for new in objects:
            if isinstance(new, self.cls):
                if master is None:
                    master = new
                else:
                    slaves.add(new)
                for item in new.items:
                    existing = self.lookup.get(item)
                    if existing is not None:
                        slaves.add(existing)
            else:
                cluster = self.lookup.get(new)
                if cluster is None:
                    #print "solitaire", new
                    solitaire.add(new)
                elif master is None:
                    #print "starting master", new
                    master = cluster
                elif master != cluster:
                    #print "in slave", new
                    slaves.add(cluster)
                #else:
                    ##nothing to do
                    #print "new in master", new

        if master is None:
            master = self.cls([])

        for slave in slaves:
            master.update(slave)
        for item in solitaire:
            master.add_item(item)

        for item in master.items:
            self.lookup[item] = master

Response: Add related items to the common cluster.


Instruction:
Write a Python 3 script to
read a single time frame from the trajectory.

Response:
def _read_frame(self):
        """Read a single frame from the trajectory"""
        # auxiliary read function
        def read_three(msg):
            """Read three words as floating point numbers"""
            line = next(self._f)
            try:
                return [float(line[:12]), float(line[12:24]), float(line[24:])]
            except ValueError:
                raise FileFormatError(msg)

        frame = {}
        # read the frame header line
        words = next(self._f).split()
        if len(words) != 6:
            raise FileFormatError("The first line of each time frame must contain 6 words. (%i'th frame)" % self._counter)
        if words[0] != "timestep":
            raise FileFormatError("The first word of the first line of each time frame must be 'timestep'. (%i'th frame)" % self._counter)
        try:
            step = int(words[1])
            frame["step"] = step
            if int(words[2]) != self.num_atoms:
                raise FileFormatError("The number of atoms has changed. (%i'th frame, %i'th step)" % (self._counter, step))
            if int(words[3]) != self.keytrj:
                raise FileFormatError("keytrj has changed. (%i'th frame, %i'th step)" % (self._counter, step))
            if int(words[4]) != self.imcon:
                raise FileFormatError("imcon has changed. (%i'th frame, %i'th step)" % (self._counter, step))
            frame["timestep"] = float(words[5])*self.time_unit
            frame["time"] = frame["timestep"]*step # this is ugly, or wait ... dlpoly is a bit ugly. we are not to blame!
        except ValueError:
            raise FileFormatError("Could not convert all numbers on the first line of the current time frame. (%i'th frame)" % self._counter)
        # the three cell lines
        cell = np.zeros((3, 3), float)
        frame["cell"] = cell
        cell_msg = "The cell lines must consist of three floating point values. (%i'th frame, %i'th step)" % (self._counter, step)
        for i in range(3):
            cell[:, i] = read_three(cell_msg)
        cell *= self.pos_unit
        # the atoms
        symbols = []
        frame["symbols"] = symbols
        masses = np.zeros(self.num_atoms, float)
        frame["masses"] = masses
        charges = np.zeros(self.num_atoms, float)
        frame["charges"] = charges
        pos = np.zeros((self.num_atoms, 3), float)
        frame["pos"] = pos
        if self.keytrj > 0:
            vel = np.zeros((self.num_atoms, 3), float)
            frame["vel"] = vel
        if self.keytrj > 1:
            frc = np.zeros((self.num_atoms, 3), float)
            frame["frc"] = frc
        for i in range(self.num_atoms):
            # the atom header line
            words = next(self._f).split()
            if len(words) != 4:
                raise FileFormatError("The atom header line must contain 4 words. (%i'th frame, %i'th step, %i'th atom)" % (self._counter, step, i+1))
            symbols.append(words[0])
            try:
                masses[i] = float(words[2])*self.mass_unit
                charges[i] = float(words[3])
            except ValueError:
                raise FileFormatError("The numbers in the atom header line could not be interpreted.")
            # the pos line
            pos_msg = "The position lines must consist of three floating point values. (%i'th frame, %i'th step, %i'th atom)" % (self._counter, step, i+1)
            pos[i] = read_three(pos_msg)
            if self.keytrj > 0:
                vel_msg = "The velocity lines must consist of three floating point values. (%i'th frame, %i'th step, %i'th atom)" % (self._counter, step, i+1)
                vel[i] = read_three(vel_msg)
            if self.keytrj > 1:
                frc_msg = "The force lines must consist of three floating point values. (%i'th frame, %i'th step, %i'th atom)" % (self._counter, step, i+1)
                frc[i] = read_three(frc_msg)
        pos *= self.pos_unit # convert to au
        if self.keytrj > 0:
            vel *= self.vel_unit # convert to au
        if self.keytrj > 1:
            frc *= self.frc_unit # convert to au
        return frame


Instruction:
Given the following Python 3 function, write the documentation
def goto_next_frame(self):
        marked = False
        while True:
            line = next(self._f)[:-1]
            if marked and len(line) > 0 and not line.startswith(" --------"):
                try:
                    step = int(line[:10])
                    return step, line
                except ValueError:
                    pass
            marked = (len(line) == 131 and line == self._marker)

Response: Continue reading until the next frame is reached


Instruction:
Can you tell what is the following Python 3 function doing
def _read_frame(self):
        # optionally skip the equilibration
        if self.skip_equi_period:
            while True:
                step, line = self.goto_next_frame()
                self._counter += 1
                if step >= self.equi_period:
                    break
            self.skip_equi_period = False
        else:
            step, line = self.goto_next_frame()

        # read the three lines
        try:
            row = [step]
            for i in range(9):
                row.append(float(line[10+i*12:10+(i+1)*12]))
            line = next(self._f)[:-1]
            row.append(float(line[:10]))
            for i in range(9):
                row.append(float(line[10+i*12:10+(i+1)*12]))
            line = next(self._f)[:-1]
            row.append(float(line[:10]))
            for i in range(9):
                row.append(float(line[10+i*12:10+(i+1)*12]))
        except ValueError:
            raise FileFormatError("Some numbers in the output file could not be read. (expecting floating point numbers)")

        # convert all the numbers to atomic units
        for i in range(30):
            row[i] *= self._conv[i]

        # done
        return row

Response: Read a single frame from the trajectory


Instruction:
Given the following Python 3 function, write the documentation
def _read_frame(self):

        size = self.read_size()
        title = self._f.readline()[:-1]
        if self.symbols is None:
            symbols = []
        coordinates = np.zeros((size, 3), float)
        for counter in range(size):
            line = self._f.readline()
            if len(line) == 0:
                raise StopIteration
            words = line.split()
            if len(words) < 4:
                raise StopIteration
            if self.symbols is None:
                symbols.append(words[0])
            try:
                coordinates[counter, 0] = float(words[1])
                coordinates[counter, 1] = float(words[2])
                coordinates[counter, 2] = float(words[3])
            except ValueError:
                raise StopIteration
        coordinates *= self.file_unit
        if self.symbols is None:
            self.symbols = symbols
        return title, coordinates

Response: Read a single frame from the XYZ file


Instruction:
Can you implement a function in Python 3 that
skips a single frame from the trajectory

Response:
def _skip_frame(self):
        """Skip a single frame from the trajectory"""
        size = self.read_size()
        for i in range(size+1):
            line = self._f.readline()
            if len(line) == 0:
                raise StopIteration


Instruction:
How would you code a function in Python 3 to
get the first molecule from the trajectory

Response:
def get_first_molecule(self):
        """Get the first molecule from the trajectory

           This can be useful to configure your program before handeling the
           actual trajectory.
        """
        title, coordinates = self._first
        molecule = Molecule(self.numbers, coordinates, title, symbols=self.symbols)
        return molecule


Instruction:
Can you tell what is the following Python 3 function doing
def dump(self, title, coordinates):
        print("% 8i" % len(self.symbols), file=self._f)
        print(str(title), file=self._f)
        for symbol, coordinate in zip(self.symbols, coordinates):
            print("% 2s % 12.9f % 12.9f % 12.9f" % ((symbol, ) + tuple(coordinate/self.file_unit)), file=self._f)

Response: Dump a frame to the trajectory file


Instruction:
Make a summary of the following Python 3 code
def get_molecule(self, index=0):
        return Molecule(self.numbers, self.geometries[index], self.titles[index], symbols=self.symbols)

Response:
Returns a Molecule object from the trajectory

           Optional argument index = 0


Instruction:
How would you explain what the following Python 3 function does
def write_to_file(self, f, file_unit=angstrom):
        xyz_writer = XYZWriter(f, self.symbols, file_unit=file_unit)
        for title, coordinates in zip(self.titles, self.geometries):
            xyz_writer.dump(title, coordinates)

Response: Write the trajectory to a file


Instruction:
Explain what the following Python 3 code does
def slice_match(sub, counter):

    if sub.start is not None and counter < sub.start:
        return False
    if sub.stop is not None and counter >= sub.stop:
        raise StopIteration
    if sub.step is not None:
        if sub.start is None:
            if counter % sub.step != 0:
                return False
        else:
            if (counter - sub.start) % sub.step != 0:
                return False
    return True

Response: Efficiently test if the counter is in the sequence of objects in the object.


Instruction:
Write a Python 3 function that can
check the analytical gradient using finite differences

Response:
def check_anagrad(fun, x0, epsilon, threshold):
    """Check the analytical gradient using finite differences

       Arguments:
        | ``fun``  --  the function to be tested, more info below
        | ``x0``  --  the reference point around which the function should be
                      tested
        | ``epsilon``  --  a small scalar used for the finite differences
        | ``threshold``  --  the maximum acceptable difference between the
                             analytical gradient and the gradient obtained by
                             finite differentiation

       The function ``fun`` takes a mandatory argument ``x`` and an optional
       argument ``do_gradient``:
        | ``x``  --  the arguments of the function to be tested
        | ``do_gradient``  --  When False, only the function value is returned.
                               When True, a 2-tuple with the function value and
                               the gradient are returned [default=False]
    """
    N = len(x0)
    f0, ana_grad = fun(x0, do_gradient=True)
    for i in range(N):
        xh = x0.copy()
        xh[i] += 0.5*epsilon
        xl = x0.copy()
        xl[i] -= 0.5*epsilon
        num_grad_comp = (fun(xh)-fun(xl))/epsilon
        if abs(num_grad_comp - ana_grad[i]) > threshold:
            raise AssertionError("Error in the analytical gradient, component %i, got %s, should be about %s" % (i, ana_grad[i], num_grad_comp))


Instruction:
Create a Python 3 function to
check the difference between two functions using the analytical gradient.

Response:
def check_delta(fun, x, dxs, period=None):
    """Check the difference between two function values using the analytical gradient

       Arguments:
        | ``fun``  --  The function to be tested, more info below.
        | ``x``  --  The argument vector.
        | ``dxs``  --  A matrix where each row is a vector of small differences
                       to be added to the argument vector.

       Optional argument:
        | ``period``  --  If the function value is periodic, one may provide the
                          period such that differences are computed using
                          periodic boundary conditions.

       The function ``fun`` takes a mandatory argument ``x`` and an optional
       argument ``do_gradient``:
        | ``x``  --  The arguments of the function to be tested.
        | ``do_gradient``  --  When False, only the function value is returned.
                               When True, a 2-tuple with the function value and
                               the gradient are returned. [default=False]

       For every row in dxs, the following computation is repeated:

       1) D1 = 'f(x+dx) - f(x)' is computed.
       2) D2 = '0.5 (grad f(x+dx) + grad f(x)) . dx' is computed.

       A threshold is set to the median of the D1 set. For each case where |D1|
       is larger than the threshold, |D1 - D2|, should be smaller than the
       threshold.
    """
    dn1s = []
    dn2s = []
    dnds = []
    for dx in dxs:
        f0, grad0 = fun(x, do_gradient=True)
        f1, grad1 = fun(x+dx, do_gradient=True)
        grad = 0.5*(grad0+grad1)
        d1 = f1 - f0
        if period is not None:
            d1 -= np.floor(d1/period + 0.5)*period
        if hasattr(d1, '__iter__'):
            norm = np.linalg.norm
        else:
            norm = abs
        d2 = np.dot(grad, dx)

        dn1s.append(norm(d1))
        dn2s.append(norm(d2))
        dnds.append(norm(d1-d2))
    dn1s = np.array(dn1s)
    dn2s = np.array(dn2s)
    dnds = np.array(dnds)

    # Get the threshold (and mask)
    threshold = np.median(dn1s)
    mask = dn1s > threshold
    # Make sure that all cases for which dn1 is above the treshold, dnd is below
    # the threshold
    if not (dnds[mask] < threshold).all():
        raise AssertionError((
            'The first order approximation on the difference is too wrong. The '
            'threshold is %.1e.\n\nDifferences:\n%s\n\nFirst order '
            'approximation to differences:\n%s\n\nAbsolute errors:\n%s')
            % (threshold,
            ' '.join('%.1e' % v for v in dn1s[mask]),
            ' '.join('%.1e' % v for v in dn2s[mask]),
            ' '.join('%.1e' % v for v in dnds[mask])
        ))


Instruction:
Write a Python 3 function that can
compute the Hessian using the finite difference method.

Response:
def compute_fd_hessian(fun, x0, epsilon, anagrad=True):
    """Compute the Hessian using the finite difference method

       Arguments:
        | ``fun``  --  the function for which the Hessian should be computed,
                       more info below
        | ``x0``  --  the point at which the Hessian must be computed
        | ``epsilon``  --  a small scalar step size used to compute the finite
                           differences

       Optional argument:
        | ``anagrad``  --  when True, analytical gradients are used
                           [default=True]

       The function ``fun`` takes a mandatory argument ``x`` and an optional
       argument ``do_gradient``:
        | ``x``  --  the arguments of the function to be tested
        | ``do_gradient``  --  When False, only the function value is returned.
                               When True, a 2-tuple with the function value and
                               the gradient are returned [default=False]
    """
    N = len(x0)

    def compute_gradient(x):
        if anagrad:
            return fun(x, do_gradient=True)[1]
        else:
            gradient = np.zeros(N, float)
            for i in range(N):
                xh = x.copy()
                xh[i] += 0.5*epsilon
                xl = x.copy()
                xl[i] -= 0.5*epsilon
                gradient[i] = (fun(xh)-fun(xl))/epsilon
            return gradient

    hessian = np.zeros((N,N), float)
    for i in range(N):
        xh = x0.copy()
        xh[i] += 0.5*epsilon
        xl = x0.copy()
        xl[i] -= 0.5*epsilon
        hessian[i] = (compute_gradient(xh) - compute_gradient(xl))/epsilon

    return 0.5*(hessian + hessian.transpose())


Instruction:
Make a summary of the following Python 3 code
def update(self, gradient, step):
        do_sd = self.gradient_old is None
        self.gradient_old = self.gradient
        self.gradient = gradient
        if do_sd:
            self._update_sd()
        else:
            self._update_cg()

Response: Update the search direction given the latest gradient and step


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _update_cg(self):
        beta = self._beta()
        # Automatic direction reset
        if beta < 0:
            self.direction = -self.gradient
            self.status = "SD"
        else:
            self.direction = self.direction * beta - self.gradient
            self.status = "CG"

Response: Update the conjugate gradient


Instruction:
Create a Python 3 function for
updating the search direction given the latest gradient and step

Response:
def update(self, gradient, step):
        """Update the search direction given the latest gradient and step"""
        self.old_gradient = self.gradient
        self.gradient = gradient
        N = len(self.gradient)
        if self.inv_hessian is None:
            # update the direction
            self.direction = -self.gradient
            self.status = "SD"
            # new guess of the inverse hessian
            self.inv_hessian = np.identity(N, float)
        else:
            # update the direction
            self.direction = -np.dot(self.inv_hessian, self.gradient)
            self.status = "QN"
            # new guess of the inverse hessian (BFGS)
            y = self.gradient - self.old_gradient
            s = step
            sy = abs(np.dot(s, y))+1e-5
            A = np.outer(-y/sy, s)
            A.ravel()[::N+1] += 1
            self.inv_hessian = (
                np.dot(np.dot(A.transpose(), self.inv_hessian), A) +
                np.outer(s/sy, s)
            )


Instruction:
Can you generate the documentation for the following Python 3 function
def limit_step(self, step):
        if self.qmax is None:
            return step
        else:
            return np.clip(step, -self.qmax, self.qmax)

Response: Clip the a step within the maximum allowed range


Instruction:
Given the following Python 3 function, write the documentation
def _bracket(self, qinit, f0, fun):
        self.num_bracket = 0
        qa = qinit
        fa = fun(qa)
        counter = 0
        if fa >= f0:
            while True:
                self.num_bracket += 1
                #print "    bracket shrink"
                qb, fb = qa, fa
                qa /= 1+phi
                fa = fun(qa)
                if qa < self.qtol:
                    return
                if fa < f0:
                    return (0, f0), (qa, fa), (qb, fb)
                counter += 1
                if self.max_iter is not None and counter > self.max_iter:
                    return
        else:
            self.num_bracket += 1
            #print "    bracket grow1"
            qb, fb = qa, fa
            qa *= (1+phi)
            fa = fun(qa)
            if fa >= fb:
                return (0, f0), (qb, fb), (qa, fa)
            while True:
                self.num_bracket += 1
                #print "    bracket grow2"
                qc, fc = qb, fb
                qb, fb = qa, fa
                qa = qb*(1+phi) - qc
                fa = fun(qa)
                if fa >= fb:
                    return (qc, fc), (qb, fb), (qa, fa)
                counter += 1
                if self.max_iter is not None and counter > self.max_iter:
                    return

Response: Find a bracket that does contain the minimum


Instruction:
How would you implement a function in Python 3 that
reduces the size of the bracket until the minimum is found

Response:
def _golden(self, triplet, fun):
        """Reduce the size of the bracket until the minimum is found"""
        self.num_golden = 0
        (qa, fa), (qb, fb), (qc, fc) = triplet
        while True:
            self.num_golden += 1
            qd = qa + (qb-qa)*phi/(1+phi)
            fd = fun(qd)
            if fd < fb:
                #print "golden d"
                (qa, fa), (qb, fb) = (qb, fb), (qd, fd)
            else:
                #print "golden b"
                (qa, fa), (qc, fc) = (qd, fd), (qa, fa)
            if abs(qa-qb) < self.qtol:
                return qc, fc


Instruction:
Can you tell what is the following Python 3 function doing
def update(self, counter, f, x_orig, gradient_orig):
        if counter - self.last_update > self.each:
            grad_rms = np.sqrt((gradient_orig**2).mean())
            if grad_rms < self.grad_rms:
                self.last_update = counter
                return True
        return False

Response: Perform an update of the linear transformation of the given object.


Instruction:
Here you have a function in Python 3, explain what it does
def update(self, counter, f, x_orig, gradient_orig):
        do_update = Preconditioner.update(self, counter, f, x_orig, gradient_orig)
        if do_update:
            # determine a new preconditioner
            N = len(x_orig)
            if self.scales is None:
                self.scales = np.ones(N, float)
            for i in range(N):
                epsilon = self.epsilon/self.scales[i]
                xh = x_orig.copy()
                xh[i] += 0.5*epsilon
                fh = self.fun(xh)
                xl = x_orig.copy()
                xl[i] -= 0.5*epsilon
                fl = self.fun(xl)
                curv = (fh+fl-2*f)/epsilon**2
                self.scales[i] = np.sqrt(abs(curv))
            if self.scales.max() <= 0:
                self.scales = np.ones(N, float)
            else:
                self.scales /= self.scales.max()
                self.scales[self.scales<self.scale_limit] = self.scale_limit
        return do_update

Response: Perform an update of the linear transformation of the minimizer.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def update(self, counter, f, x_orig, gradient_orig):
        if Preconditioner.update(self, counter, f, x_orig, gradient_orig):
            # determine a new preconditioner
            hessian = compute_fd_hessian(self.fun, x_orig, self.epsilon)
            evals, evecs = np.linalg.eigh(hessian)
            self.scales = np.sqrt(abs(evals))+self.epsilon
            self.rotation = evecs
            return True
        return False

Response: Perform an update of the linear transformation of the minimizer.


Instruction:
Here you have a function in Python 3, explain what it does
def do(self, x_orig):
        if self.scales is None:
            return x_orig
        else:
            return np.dot(self.rotation.transpose(), x_orig)*self.scales

Response:
Transform the unknowns to preconditioned coordinates

           This method transforms the gradient to original coordinates


Instruction:
Can you implement a function in Python 3 that
transforms the unknowns to original coordinates This method also transforms the gradient to preconditioned coordinates Integrity

Response:
def undo(self, x_prec):
        """Transform the unknowns to original coordinates

           This method also transforms the gradient to preconditioned coordinates
        """
        if self.scales is None:
            return x_prec
        else:
            return np.dot(self.rotation, x_prec/self.scales)


Instruction:
Can you tell what is the following Python 3 function doing
def get_header(self):
        result = " "
        if self.step_rms is not None:
            result += "    Step RMS"
        if self.step_max is not None:
            result += "    Step MAX"
        if self.grad_rms is not None:
            result += "    Grad RMS"
        if self.grad_max is not None:
            result += "    Grad MAX"
        if self.rel_grad_rms is not None:
            result += "  Grad/F RMS"
        if self.rel_grad_max is not None:
            result += "  Grad/F MAX"
        return result

Response: Returns the header for screen logging of the minimization


Instruction:
Implement a function in Python 3 to
configure the 1D function for a line search

Response:
def configure(self, x0, axis):
        """Configure the 1D function for a line search

           Arguments:
             x0  --  the reference point (q=0)
             axis  --  a unit vector in the direction of the line search
        """
        self.x0 = x0
        self.axis = axis


Instruction:
Write a Python 3 function for
computing the values and normals of active constraints.

Response:
def _compute_equations(self, x, verbose=False):
        '''Compute the values and the normals (gradients) of active constraints.

           Arguments:
            | ``x`` -- The unknowns.
        '''
        # compute the error and the normals.
        normals = []
        values = []
        signs = []
        error = 0.0
        if verbose:
            print()
            print(' '.join('% 10.3e' % val for val in x), end=' ')
            active_str = ''
        for i, (sign, equation) in enumerate(self.equations):
            value, normal = equation(x)
            if (i < len(self.lock) and self.lock[i]) or \
               (sign==-1 and value > -self.threshold) or \
               (sign==0) or (sign==1 and value < self.threshold):
                values.append(value)
                normals.append(normal)
                signs.append(sign)
                error += value**2
                if verbose:
                    active_str += 'X'
                if i < len(self.lock):
                    self.lock[i] = True
            elif verbose:
                active_str += '-'
        error = np.sqrt(error)
        normals = np.array(normals, float)
        values = np.array(values, float)
        signs = np.array(signs, int)
        if verbose:
            print('[%s]' % active_str, end=' ')
            if error < self.threshold:
                print('OK')
            else:
                print('%.5e' % error)
        return normals, values, error, signs