Esempio n. 1
0
def test():
    """Guassian/Neural force call.

    Checks consistency of pure-python and fortran versions.
    """

    images = make_images()

    for fortran in [False, True]:
        label = 'forcecall/%s' % fortran
        calc = Amp(
            descriptor=Gaussian(
                cutoff=cutoff,
                Gs=Gs,
                fortran=fortran,
            ),
            model=NeuralNetwork(
                hiddenlayers=hiddenlayers,
                weights=weights,
                scalings=scalings,
                activation=activation,
                mode='atom-centered',
                fprange=fingerprints_range,
                fortran=fortran,
            ),
            label=label,
        )

        if fortran is False:
            reference_energies = [
                calc.get_potential_energy(image) for image in images
            ]
        else:
            predicted_energies = [
                calc.get_potential_energy(image) for image in images
            ]
            for image_no in range(len(predicted_energies)):
                assert (abs(predicted_energies[image_no] -
                            reference_energies[image_no]) < 10.**(-5.)), \
                    'Calculated energy value of image %i by \
                    fortran version is not consistent with the \
                    value of python version.'                                              % (image_no + 1)

        if fortran is False:
            reference_forces = [calc.get_forces(image) for image in images]
        else:
            predicted_forces = [calc.get_forces(image) for image in images]

            for image_no in range(len(predicted_forces)):
                for index in range(np.shape(predicted_forces[image_no])[0]):
                    for k in range(np.shape(predicted_forces[image_no])[1]):
                        assert (abs(predicted_forces[image_no][index][k] -
                                    reference_forces[image_no][index][k]) <
                                10.**(-5.)), \
                            'Calculated %i force of atom %i of \
                            image %i by fortran version is not  \
                            consistent with the value of python \
                            version.'                                      % (k, index, image_no + 1)
Esempio n. 2
0
def train_test():
    label = 'train_test_g5/calc'
    train_images = generate_data(2)
    elements = ['Pt', 'Cu']
    G = make_symmetry_functions(elements=elements,
                                type='G2',
                                etas=np.logspace(np.log10(0.05),
                                                 np.log10(5.),
                                                 num=4))
    G += make_symmetry_functions(elements=elements,
                                 type='G5',
                                 etas=[0.005],
                                 zetas=[1., 4.],
                                 gammas=[+1., -1.])

    G = {element: G for element in elements}

    calc = Amp(descriptor=Gaussian(Gs=G),
               model=NeuralNetwork(hiddenlayers=(3, 3)),
               label=label,
               cores=1)
    loss = LossFunction(convergence={'energy_rmse': 0.02, 'force_rmse': 0.03})
    calc.model.lossfunction = loss

    calc.train(images=train_images, )
    for image in train_images:
        print("energy = %s" % str(calc.get_potential_energy(image)))
        print("forces = %s" % str(calc.get_forces(image)))

    # Test that we can re-load this calculator and call it again.
    del calc
    calc2 = Amp.load(label + '.amp')
    for image in train_images:
        print("energy = %s" % str(calc2.get_potential_energy(image)))
        print("forces = %s" % str(calc2.get_forces(image)))
Esempio n. 3
0
def train_test():
    """Gaussian/KRR train test."""
    label = 'train_test/calc'
    train_images = generate_data(2)
    traj = Trajectory('trainingset.traj', mode='w')

    for image in train_images:
        traj.write(image)

    calc = Amp(descriptor=Gaussian(),
               model=KernelRidge(forcetraining=True, trainingimages='trainingset.traj'),
               label=label,
               cores=1)

    calc.train(images=train_images,)
    for image in train_images:
        print("energy = %s" % str(calc.get_potential_energy(image)))
        print("forces = %s" % str(calc.get_forces(image)))

    # Test that we can re-load this calculator and call it again.
    del calc
    calc2 = Amp.load(label + '.amp')
    for image in train_images:
        print("energy = %s" % str(calc2.get_potential_energy(image)))
        print("forces = %s" % str(calc2.get_forces(image)))
Esempio n. 4
0
def train_data(images, setup_only=False):
    label = 'nodeplot_test/calc'
    train_images = images

    calc = Amp(descriptor=Gaussian(),
               model=NeuralNetwork(hiddenlayers=(5, 5)),
               label=label,
               cores=1)
    loss = LossFunction(convergence={'energy_rmse': 0.02, 'force_rmse': 0.02})
    calc.model.lossfunction = loss

    if not setup_only:
        calc.train(images=train_images, )
        for image in train_images:
            print("energy =", calc.get_potential_energy(image))
            print("forces =", calc.get_forces(image))
    else:
        images = hash_images(train_images)
        calc.descriptor.calculate_fingerprints(images=images,
                                               log=calc._log,
                                               parallel={'cores': 1},
                                               calculate_derivatives=False)
        calc.model.fit(trainingimages=images,
                       descriptor=calc.descriptor,
                       log=calc._log,
                       parallel={'cores': 1},
                       only_setup=True)
        return calc
def train_data(images, setup_only=False):
    label = 'nodeplot_test/calc'
    train_images = images

    calc = Amp(descriptor=Gaussian(),
               model=NeuralNetwork(hiddenlayers=(5, 5)),
               label=label,
               cores=1)
    loss = LossFunction(convergence={'energy_rmse': 0.02,
                                     'force_rmse': 0.02})
    calc.model.lossfunction = loss

    if not setup_only:
        calc.train(images=train_images, )
        for image in train_images:
            print "energy =", calc.get_potential_energy(image)
            print "forces =", calc.get_forces(image)
    else:
        images = hash_images(train_images)
        calc.descriptor.calculate_fingerprints(images=images,
                                               log=calc.log,
                                               cores=1,
                                               calculate_derivatives=False)
        calc.model.fit(trainingimages=images,
                       descriptor=calc.descriptor,
                       log=calc.log,
                       cores=1,
                       only_setup=True)
        return calc
def test():

    images = make_images()

    for fortran in [False, True]:
        label = 'forcecall/%s' % fortran
        calc = Amp(descriptor=Gaussian(cutoff=cutoff,
                                       Gs=Gs,
                                       fortran=fortran,),
                   model=NeuralNetwork(hiddenlayers=hiddenlayers,
                                       weights=weights,
                                       scalings=scalings,
                                       activation=activation,
                                       mode='atom-centered',
                                       fprange=fingerprints_range,
                                       fortran=fortran,),
                   label=label,)

        if fortran is False:
            reference_energies = [calc.get_potential_energy(image)
                                  for image in images]
        else:
            predicted_energies = [calc.get_potential_energy(image)
                                  for image in images]
            for image_no in range(len(predicted_energies)):
                assert (abs(predicted_energies[image_no] -
                            reference_energies[image_no]) < 10.**(-5.)), \
                    'Calculated energy value of image %i by \
                    fortran version is not consistent with the \
                    value of python version.' % (image_no + 1)

        if fortran is False:
            reference_forces = [calc.get_forces(image) for image in images]
        else:
            predicted_forces = [calc.get_forces(image) for image in images]

            for image_no in range(len(predicted_forces)):
                for index in range(np.shape(predicted_forces[image_no])[0]):
                    for k in range(np.shape(predicted_forces[image_no])[1]):
                        assert (abs(predicted_forces[image_no][index][k] -
                                    reference_forces[image_no][index][k]) <
                                10.**(-5.)), \
                            'Calculated %i force of atom %i of \
                            image %i by fortran version is not  \
                            consistent with the value of python \
                            version.' % (k, index, image_no + 1)
def train_test():
    label = 'train_test/calc'
    train_images = generate_data(2)

    calc = Amp(descriptor=Gaussian(),
               model=NeuralNetwork(hiddenlayers=(3, 3)),
               label=label,
               cores=1)
    loss = LossFunction(convergence={'energy_rmse': 0.02,
                                     'force_rmse': 0.02})
    calc.model.lossfunction = loss

    calc.train(images=train_images,)
    for image in train_images:
        print "energy =", calc.get_potential_energy(image)
        print "forces =", calc.get_forces(image)
Esempio n. 8
0
def train_test():
    """Gaussian/tflow train test."""
    perform, reason = check_perform()
    if not perform:
        print('Skipping this test because {}.'.format(reason))
        return

    from amp.model.tflow import NeuralNetwork
    label = 'train_test/calc'
    train_images = generate_data(2)
    convergence = {'energy_rmse': 0.02, 'force_rmse': 0.02}

    calc = Amp(descriptor=Gaussian(),
               model=NeuralNetwork(hiddenlayers=(3, 3),
                                   convergenceCriteria=convergence),
               label=label,
               cores=1)

    calc.train(images=train_images, )
    for image in train_images:
        print("energy =", calc.get_potential_energy(image))
        print("forces =", calc.get_forces(image))
Esempio n. 9
0
def train_test():
    """Gaussian/Neural train test."""
    label = 'train_test/calc'
    train_images = generate_data(2)

    calc = Amp(descriptor=Gaussian(),
               model=NeuralNetwork(hiddenlayers=(3, 3)),
               label=label,
               cores=1)
    loss = LossFunction(convergence={'energy_rmse': 0.02, 'force_rmse': 0.03})
    calc.model.lossfunction = loss

    calc.train(images=train_images, )
    for image in train_images:
        print("energy = %s" % str(calc.get_potential_energy(image)))
        print("forces = %s" % str(calc.get_forces(image)))

    # Test that we can re-load this calculator and call it again.
    del calc
    calc2 = Amp.load(label + '.amp')
    for image in train_images:
        print("energy = %s" % str(calc2.get_potential_energy(image)))
        print("forces = %s" % str(calc2.get_forces(image)))
def test_calcs():
    """Gaussian/Neural non-periodic standard.

    Checks that the answer matches that expected from previous Mathematica
    calculations.
    """

    #: Making the list of non-periodic images
    images = [
        Atoms(
            symbols="PdOPd2",
            pbc=np.array([False, False, False], dtype=bool),
            calculator=EMT(),
            cell=np.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]),
            positions=np.array([[0.0, 0.0, 0.0], [0.0, 2.0, 0.0],
                                [0.0, 0.0, 3.0], [1.0, 0.0, 0.0]]),
        ),
        Atoms(
            symbols="PdOPd2",
            pbc=np.array([False, False, False], dtype=bool),
            calculator=EMT(),
            cell=np.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]),
            positions=np.array([[0.0, 1.0, 0.0], [1.0, 2.0, 1.0],
                                [-1.0, 1.0, 2.0], [1.0, 3.0, 2.0]]),
        ),
        Atoms(
            symbols="PdO",
            pbc=np.array([False, False, False], dtype=bool),
            calculator=EMT(),
            cell=np.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]),
            positions=np.array([[2.0, 1.0, -1.0], [1.0, 2.0, 1.0]]),
        ),
        Atoms(
            symbols="Pd2O",
            pbc=np.array([False, False, False], dtype=bool),
            calculator=EMT(),
            cell=np.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]),
            positions=np.array([[-2.0, -1.0, -1.0], [1.0, 2.0, 1.0],
                                [3.0, 4.0, 4.0]]),
        ),
        Atoms(
            symbols="Cu",
            pbc=np.array([False, False, False], dtype=bool),
            calculator=EMT(),
            cell=np.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]),
            positions=np.array([[0.0, 0.0, 0.0]]),
        ),
    ]

    [a.get_potential_energy() for a in images]
    # Parameters
    hiddenlayers = {"O": (2, ), "Pd": (2, ), "Cu": (2, )}

    Gs = {}
    Gs["G2_etas"] = [0.2]
    Gs["G2_rs_s"] = [0]
    Gs["G4_etas"] = [0.4]
    Gs["G4_zetas"] = [1]
    Gs["G4_gammas"] = [1]
    Gs["cutoff"] = 6.5

    elements = ["O", "Pd", "Cu"]

    G = make_symmetry_functions(elements=elements,
                                type="G2",
                                etas=Gs["G2_etas"])
    G += make_symmetry_functions(
        elements=elements,
        type="G4",
        etas=Gs["G4_etas"],
        zetas=Gs["G4_zetas"],
        gammas=Gs["G4_gammas"],
    )
    hashed_images = hash_images(images, Gs)
    descriptor = Gaussian(Gs=G, cutoff=Gs["cutoff"])
    descriptor.calculate_fingerprints(hashed_images,
                                      calculate_derivatives=True)
    fingerprints_range = calculate_fingerprints_range(descriptor,
                                                      hashed_images)

    weights = OrderedDict([
        (
            "O",
            OrderedDict([
                (
                    1,
                    np.array([
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                    ]),
                ),
                (2, np.matrix([[0.5], [0.5], [0.5]])),
            ]),
        ),
        (
            "Pd",
            OrderedDict([
                (
                    1,
                    np.array([
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                    ]),
                ),
                (2, np.array([[0.5], [0.5], [0.5]])),
            ]),
        ),
        (
            "Cu",
            OrderedDict([
                (
                    1,
                    np.array([
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                    ]),
                ),
                (2, np.array([[0.5], [0.5], [0.5]])),
            ]),
        ),
    ])

    scalings = OrderedDict([
        ("O", OrderedDict([("intercept", 0), ("slope", 1)])),
        ("Pd", OrderedDict([("intercept", 0), ("slope", 1)])),
        ("Cu", OrderedDict([("intercept", 0), ("slope", 1)])),
    ])

    calc = Amp(
        descriptor,
        model=NeuralNetwork(
            hiddenlayers=hiddenlayers,
            weights=weights,
            scalings=scalings,
            activation="linear",
            fprange=fingerprints_range,
            mode="atom-centered",
            fortran=False,
        ),
        logging=False,
    )

    amp_energies = [calc.get_potential_energy(image) for image in images]
    amp_forces = [calc.get_forces(image) for image in images]
    amp_forces = np.concatenate(amp_forces)

    device = "cpu"
    dataset = AtomsDataset(images,
                           descriptor=DummyGaussian,
                           cores=1,
                           label='test',
                           Gs=Gs,
                           forcetraining=True)
    fp_length = dataset.fp_length
    batch_size = len(dataset)
    dataloader = DataLoader(dataset,
                            batch_size,
                            collate_fn=collate_amp,
                            shuffle=False)
    model = FullNN(elements, [fp_length, 2, 2], device, forcetraining=True)
    for name, layer in model.named_modules():
        if isinstance(layer, Dense):
            layer.activation = None
            init.constant_(layer.weight, 0.5)
            init.constant_(layer.bias, 0.5)
    for batch in dataloader:
        input_data = [batch[0], len(batch[1]), batch[3]]
        for element in elements:
            input_data[0][element][0] = (
                input_data[0][element][0].to(device).requires_grad_(True))
        fp_primes = batch[4]
        energy_pred, force_pred = model(input_data, fp_primes)

    for idx, i in enumerate(amp_energies):
        assert round(i, 4) == round(
            energy_pred.tolist()[idx][0],
            4), "The predicted energy of image %i is wrong!" % (idx + 1)
    print("Energy predictions are correct!")
    for idx, sample in enumerate(amp_forces):
        for idx_d, value in enumerate(sample):
            predict = force_pred.tolist()[idx][idx_d]
            assert abs(value - predict) < 0.00001, (
                "The predicted force of image % i, direction % i is wrong! Values: %s vs %s"
                % (idx + 1, idx_d, value, force_pred.tolist()[idx][idx_d]))
    print("Force predictions are correct!")
Esempio n. 11
0
def test_calcs():
    """Gaussian/Neural non-periodic standard.

    Checks that the answer matches that expected from previous Mathematica
    calculations.
    """

    #: Making the list of non-periodic images
    images = [
        Atoms(
            symbols="PdOPd2",
            pbc=np.array([False, False, False], dtype=bool),
            calculator=EMT(),
            cell=np.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]),
            positions=np.array([[0.0, 0.0, 0.0], [0.0, 2.0, 0.0],
                                [0.0, 0.0, 3.0], [1.0, 0.0, 0.0]]),
        ),
        Atoms(
            symbols="PdOPd2",
            pbc=np.array([False, False, False], dtype=bool),
            calculator=EMT(),
            cell=np.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]),
            positions=np.array([[0.0, 1.0, 0.0], [1.0, 2.0, 1.0],
                                [-1.0, 1.0, 2.0], [1.0, 3.0, 2.0]]),
        ),
        Atoms(
            symbols="PdO",
            pbc=np.array([False, False, False], dtype=bool),
            calculator=EMT(),
            cell=np.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]),
            positions=np.array([[2.0, 1.0, -1.0], [1.0, 2.0, 1.0]]),
        ),
        Atoms(
            symbols="Pd2O",
            pbc=np.array([False, False, False], dtype=bool),
            calculator=EMT(),
            cell=np.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]),
            positions=np.array([[-2.0, -1.0, -1.0], [1.0, 2.0, 1.0],
                                [3.0, 4.0, 4.0]]),
        ),
        Atoms(
            symbols="Cu",
            pbc=np.array([False, False, False], dtype=bool),
            calculator=EMT(),
            cell=np.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]),
            positions=np.array([[0.0, 0.0, 0.0]]),
        ),
    ]

    # Parameters
    hiddenlayers = {"O": (2, ), "Pd": (2, ), "Cu": (2, )}

    Gs = {}
    Gs["G2_etas"] = [0.2]
    Gs["G2_rs_s"] = [0]
    Gs["G4_etas"] = [0.4]
    Gs["G4_zetas"] = [1]
    Gs["G4_gammas"] = [1]
    Gs["cutoff"] = 6.5

    elements = ["O", "Pd", "Cu"]

    G = make_symmetry_functions(elements=elements,
                                type="G2",
                                etas=Gs["G2_etas"])
    G += make_symmetry_functions(
        elements=elements,
        type="G4",
        etas=Gs["G4_etas"],
        zetas=Gs["G4_zetas"],
        gammas=Gs["G4_gammas"],
    )
    amp_images = amp_hash(images)
    descriptor = Gaussian(Gs=G, cutoff=Gs["cutoff"])
    descriptor.calculate_fingerprints(amp_images, calculate_derivatives=True)
    fingerprints_range = calculate_fingerprints_range(descriptor, amp_images)
    np.random.seed(1)
    O_weights_1 = np.random.rand(10, 2)
    O_weights_2 = np.random.rand(1, 3).reshape(-1, 1)
    np.random.seed(2)
    Pd_weights_1 = np.random.rand(10, 2)
    Pd_weights_2 = np.random.rand(1, 3).reshape(-1, 1)
    np.random.seed(3)
    Cu_weights_1 = np.random.rand(10, 2)
    Cu_weights_2 = np.random.rand(1, 3).reshape(-1, 1)

    weights = OrderedDict([
        ("O", OrderedDict([(1, O_weights_1), (2, O_weights_2)])),
        ("Pd", OrderedDict([(1, Pd_weights_1), (2, Pd_weights_2)])),
        ("Cu", OrderedDict([(1, Cu_weights_1), (2, Cu_weights_2)])),
    ])

    scalings = OrderedDict([
        ("O", OrderedDict([("intercept", 0), ("slope", 1)])),
        ("Pd", OrderedDict([("intercept", 0), ("slope", 1)])),
        ("Cu", OrderedDict([("intercept", 0), ("slope", 1)])),
    ])

    calc = Amp(
        descriptor,
        model=NeuralNetwork(
            hiddenlayers=hiddenlayers,
            weights=weights,
            scalings=scalings,
            activation="tanh",
            fprange=fingerprints_range,
            mode="atom-centered",
            fortran=False,
        ),
        logging=False,
    )

    amp_energies = [calc.get_potential_energy(image) for image in images]
    amp_forces = [calc.get_forces(image) for image in images]
    amp_forces = np.concatenate(amp_forces)

    torch_O_weights_1 = torch.FloatTensor(O_weights_1[:-1, :]).t()
    torch_O_bias_1 = torch.FloatTensor(O_weights_1[-1, :])
    torch_O_weights_2 = torch.FloatTensor(O_weights_2[:-1, :]).t()
    torch_O_bias_2 = torch.FloatTensor(O_weights_2[-1, :])
    torch_Pd_weights_1 = torch.FloatTensor(Pd_weights_1[:-1, :]).t()
    torch_Pd_bias_1 = torch.FloatTensor(Pd_weights_1[-1, :])
    torch_Pd_weights_2 = torch.FloatTensor(Pd_weights_2[:-1, :]).t()
    torch_Pd_bias_2 = torch.FloatTensor(Pd_weights_2[-1, :])
    torch_Cu_weights_1 = torch.FloatTensor(Cu_weights_1[:-1, :]).t()
    torch_Cu_bias_1 = torch.FloatTensor(Cu_weights_1[-1, :])
    torch_Cu_weights_2 = torch.FloatTensor(Cu_weights_2[:-1, :]).t()
    torch_Cu_bias_2 = torch.FloatTensor(Cu_weights_2[-1, :])

    device = "cpu"
    dataset = AtomsDataset(
        images,
        descriptor=Gaussian,
        cores=1,
        label="consistency",
        Gs=Gs,
        forcetraining=True,
    )

    fp_length = dataset.fp_length
    batch_size = len(dataset)
    dataloader = DataLoader(dataset,
                            batch_size,
                            collate_fn=collate_amp,
                            shuffle=False)
    model = FullNN(elements, [fp_length, 2, 2], device, forcetraining=True)
    model.state_dict()["elementwise_models.O.model_net.0.weight"].copy_(
        torch_O_weights_1)
    model.state_dict()["elementwise_models.O.model_net.0.bias"].copy_(
        torch_O_bias_1)
    model.state_dict()["elementwise_models.O.model_net.2.weight"].copy_(
        torch_O_weights_2)
    model.state_dict()["elementwise_models.O.model_net.2.bias"].copy_(
        torch_O_bias_2)
    model.state_dict()["elementwise_models.Pd.model_net.0.weight"].copy_(
        torch_Pd_weights_1)
    model.state_dict()["elementwise_models.Pd.model_net.0.bias"].copy_(
        torch_Pd_bias_1)
    model.state_dict()["elementwise_models.Pd.model_net.2.weight"].copy_(
        torch_Pd_weights_2)
    model.state_dict()["elementwise_models.Pd.model_net.2.bias"].copy_(
        torch_Pd_bias_2)
    model.state_dict()["elementwise_models.Cu.model_net.0.weight"].copy_(
        torch_Cu_weights_1)
    model.state_dict()["elementwise_models.Cu.model_net.0.bias"].copy_(
        torch_Cu_bias_1)
    model.state_dict()["elementwise_models.Cu.model_net.2.weight"].copy_(
        torch_Cu_weights_2)
    model.state_dict()["elementwise_models.Cu.model_net.2.bias"].copy_(
        torch_Cu_bias_2)
    import torch.nn as nn
    for name, layer in model.named_modules():
        if isinstance(layer, MLP):
            layer.model_net = nn.Sequential(layer.model_net, Tanh())

    for batch in dataloader:
        x = to_tensor(batch[0], device)
        y = to_tensor(batch[1], device)
        energy_pred, force_pred = model(x)
    for idx, i in enumerate(amp_energies):
        assert round(i, 4) == round(
            energy_pred.tolist()[idx][0],
            4), "The predicted energy of image %i is wrong!" % (idx + 1)
    print("Energy predictions are correct!")
    for idx, sample in enumerate(amp_forces):
        for idx_d, value in enumerate(sample):
            predict = force_pred.tolist()[idx][idx_d]
            assert abs(value - predict) < 0.0001, (
                "The predicted force of image % i, direction % i is wrong! Values: %s vs %s"
                % (idx + 1, idx_d, value, force_pred.tolist()[idx][idx_d]))
    print("Force predictions are correct!")
Esempio n. 12
0
def non_periodic_test():
    """Gaussian/tflowNeural non-periodic."""
    perform, reason = check_perform()
    if not perform:
        print('Skipping this test because {}'.format(reason))
        return

    from amp.model.tflow import NeuralNetwork
    # Making the list of non-periodic images
    images = [Atoms(symbols='PdOPd2',
                    pbc=np.array([False, False, False], dtype=bool),
                    cell=np.array(
                        [[1.,  0.,  0.],
                         [0.,  1.,  0.],
                            [0.,  0.,  1.]]),
                    positions=np.array(
                        [[0.,  0.,  0.],
                         [0.,  2.,  0.],
                            [0.,  0.,  3.],
                            [1.,  0.,  0.]])),
              Atoms(symbols='PdOPd2',
                    pbc=np.array([False, False, False], dtype=bool),
                    cell=np.array(
                        [[1.,  0.,  0.],
                         [0.,  1.,  0.],
                            [0.,  0.,  1.]]),
                    positions=np.array(
                        [[0.,  1.,  0.],
                         [1.,  2.,  1.],
                            [-1.,  1.,  2.],
                            [1.,  3.,  2.]])),
              Atoms(symbols='PdO',
                    pbc=np.array([False, False, False], dtype=bool),
                    cell=np.array(
                        [[1.,  0.,  0.],
                         [0.,  1.,  0.],
                         [0.,  0.,  1.]]),
                    positions=np.array(
                        [[2.,  1., -1.],
                         [1.,  2.,  1.]])),
              Atoms(symbols='Pd2O',
                    pbc=np.array([False, False, False], dtype=bool),
                    cell=np.array(
                        [[1.,  0.,  0.],
                         [0.,  1.,  0.],
                         [0.,  0.,  1.]]),
                    positions=np.array(
                        [[-2., -1., -1.],
                         [1.,  2.,  1.],
                         [3.,  4.,  4.]])),
              Atoms(symbols='Cu',
                    pbc=np.array([False, False, False], dtype=bool),
                    cell=np.array(
                        [[1.,  0.,  0.],
                         [0.,  1.,  0.],
                         [0.,  0.,  1.]]),
                    positions=np.array(
                        [[0.,  0.,  0.]]))]

    # Correct energies and forces
    correct_energies = [14.231186811226152, 14.327219917287948,
                        5.5742510565528285, 9.41456771216968,
                        -0.5019297954597407]
    correct_forces = \
        [[[-0.05095024246182649, -0.10709193432146558, -0.09734321482638622],
          [-0.044550772904033635, 0.2469763195486647, -0.07617425912869778],
            [-0.02352490951707703, -0.050782839419131864, 0.24409220250631508],
            [0.11902592488293715, -0.08910154580806727, -0.07057472855123109]],
            [[-0.024868720575099375, -0.07417891957113862,
              -0.12121240797223251],
             [0.060156158438252574, 0.017517013378773042,
              -0.020047135079325505],
             [-0.10901144291312388, -0.06671262448352767, 0.06581556263014315],
             [0.07372400504997068, 0.12337453067589325, 0.07544398042141486]],
            [[0.10151747265164626, -0.10151747265164626, -0.20303494530329252],
             [-0.10151747265164626, 0.10151747265164626, 0.20303494530329252]],
            [[-0.00031177673224312745, -0.00031177673224312745,
              -0.0002078511548287517],
             [0.004823209772264884, 0.004823209772264884,
              0.006975000714861393],
             [-0.004511433040021756, -0.004511433040021756,
              -0.006767149560032641]],
            [[0.0, 0.0, 0.0]]]

    # Parameters
    Gs = {'O': [{'type': 'G2', 'element': 'Pd', 'eta': 0.8},
                {'type': 'G4', 'elements': [
                    'Pd', 'Pd'], 'eta':0.2, 'gamma':0.3, 'zeta':1},
                {'type': 'G4', 'elements': ['O', 'Pd'], 'eta':0.3, 'gamma':0.6,
                 'zeta':0.5}],
          'Pd': [{'type': 'G2', 'element': 'Pd', 'eta': 0.2},
                 {'type': 'G4', 'elements': ['Pd', 'Pd'],
                  'eta':0.9, 'gamma':0.75, 'zeta':1.5},
                 {'type': 'G4', 'elements': ['O', 'Pd'], 'eta':0.4,
                  'gamma':0.3, 'zeta':4}],
          'Cu': [{'type': 'G2', 'element': 'Cu', 'eta': 0.8},
                 {'type': 'G4', 'elements': ['Cu', 'O'],
                  'eta':0.2, 'gamma':0.3, 'zeta':1},
                 {'type': 'G4', 'elements': ['Cu', 'Cu'], 'eta':0.3,
                  'gamma':0.6, 'zeta':0.5}]}

    hiddenlayers = {'O': (2, 1), 'Pd': (2, 1), 'Cu': (2, 1)}

    weights = OrderedDict([('O', OrderedDict([(1, np.matrix([[-2.0, 6.0],
                                                             [3.0, -3.0],
                                                             [1.5, -0.9],
                                                             [-2.5, -1.5]])),
                                              (2, np.matrix([[5.5],
                                                             [3.6],
                                                             [1.4]]))])),
                           ('Pd', OrderedDict([(1, np.matrix([[-1.0, 3.0],
                                                              [2.0, 4.2],
                                                              [1.0, -0.7],
                                                              [-3.0, 2.0]])),
                                               (2, np.matrix([[4.0],
                                                              [0.5],
                                                              [3.0]]))])),
                           ('Cu', OrderedDict([(1, np.matrix([[0.0, 1.0],
                                                              [-1.0, -2.0],
                                                              [2.5, -1.9],
                                                              [-3.5, 0.5]])),
                                               (2, np.matrix([[0.5],
                                                              [1.6],
                                                              [-1.4]]))]))])

    scalings = OrderedDict([('O', OrderedDict([('intercept', -2.3),
                                               ('slope', 4.5)])),
                            ('Pd', OrderedDict([('intercept', 1.6),
                                                ('slope', 2.5)])),
                            ('Cu', OrderedDict([('intercept', -0.3),
                                                ('slope', -0.5)]))])

    fingerprints_range = {"Cu": np.array([[0.0, 0.0], [0.0, 0.0], [0.0, 0.0]]),
                          "O": np.array([[0.2139617720858539,
                                          2.258090276328769],
                                         [0.0, 1.085656080548734],
                                         [0.0, 0.0]]),
                          "Pd": np.array([[0.0, 1.4751761770313006],
                                          [0.0, 0.28464992134267897],
                                          [0.0, 0.20167521020630502]])}

    # Testing pure-python and fortran versions of Gaussian-neural force call
    for fortran in [False, True]:
        for cores in range(1, 6):
            label = 'call-nonperiodic/%s-%i' % (fortran, cores)
            calc = Amp(descriptor=Gaussian(cutoff=6.5,
                                           Gs=Gs,
                                           fortran=fortran),
                       model=NeuralNetwork(hiddenlayers=hiddenlayers,
                                           weights=weights,
                                           scalings=scalings,
                                           activation='sigmoid',
                                           fprange=fingerprints_range),
                       label=label,
                       dblabel=label,
                       cores=cores)

            predicted_energies = [calc.get_potential_energy(image) for image in
                                  images]

            for image_no in range(len(predicted_energies)):
                print(predicted_energies[image_no])
                print(correct_energies[image_no])
                diff = abs(predicted_energies[image_no] -
                           correct_energies[image_no])
                assert (diff < 10.**(-3.)), \
                    'The predicted energy of image %i is wrong!' % (
                        image_no + 1)

            predicted_forces = [calc.get_forces(image) for image in images]

            for image_no in range(len(predicted_forces)):
                print('predicted forces:')
                print(predicted_forces[image_no])
                print('correct forces:')
                print(np.array(correct_forces[image_no]))
                for index in range(np.shape(predicted_forces[image_no])[0]):
                    for direction in range(
                            np.shape(predicted_forces[image_no])[1]):
                        diff = abs(predicted_forces[image_no][index][
                            direction] -
                            correct_forces[image_no][index][direction])
                        assert (diff < 10.**(-3.)), \
                            'The predicted %i force of atom %i of image %i ' \
                            'is wrong!' % (direction, index, image_no + 1)
def periodic_test():

    # Making the list of periodic images
    images = [Atoms(symbols='PdOPd',
                    pbc=np.array([True, False, False], dtype=bool),
                    cell=np.array(
                        [[2.,  0.,  0.],
                         [0.,  2.,  0.],
                         [0.,  0.,  2.]]),
                    positions=np.array(
                        [[0.5,  1., 0.5],
                         [1.,  0.5,  1.],
                         [1.5,  1.5,  1.5]])),
              Atoms(symbols='PdO',
                    pbc=np.array([True, True, False], dtype=bool),
                    cell=np.array(
                        [[2.,  0.,  0.],
                         [0.,  2.,  0.],
                            [0.,  0.,  2.]]),
                    positions=np.array(
                        [[0.5,  1., 0.5],
                         [1.,  0.5,  1.]])),
              Atoms(symbols='Cu',
                    pbc=np.array([True, True, False], dtype=bool),
                    cell=np.array(
                        [[1.8,  0.,  0.],
                         [0.,  1.8,  0.],
                            [0.,  0.,  1.8]]),
                    positions=np.array(
                        [[0.,  0., 0.]]))]

    # Correct energies and forces
    correct_energies = [3.8560954326995978, 1.6120748520627273,
                        0.19433107801410093]
    correct_forces = \
        [[[0.14747720528015523, -3.3010645563584973, 3.3008168318984463],
          [0.03333579762326405, 9.050780376599887, -0.42608278400777605],
            [-0.1808130029034193, -5.7497158202413905, -2.8747340478906698]],
            [[6.5035267996045045 * (10.**(-6.)),
              -6.503526799604495 * (10.**(-6.)),
              0.00010834689201069249],
             [-6.5035267996045045 * (10.**(-6.)),
              6.503526799604495 * (10.**(-6.)),
              -0.00010834689201069249]],
            [[0.0, 0.0, 0.0]]]

    # Parameters
    Gs = {'O': [{'type': 'G2', 'element': 'Pd', 'eta': 0.8},
                {'type': 'G4', 'elements': ['O', 'Pd'], 'eta':0.3, 'gamma':0.6,
                 'zeta':0.5}],
          'Pd': [{'type': 'G2', 'element': 'Pd', 'eta': 0.2},
                 {'type': 'G4', 'elements': ['Pd', 'Pd'],
                  'eta':0.9, 'gamma':0.75, 'zeta':1.5}],
          'Cu': [{'type': 'G2', 'element': 'Cu', 'eta': 0.8},
                 {'type': 'G4', 'elements': ['Cu', 'Cu'], 'eta':0.3,
                          'gamma':0.6, 'zeta':0.5}]}

    hiddenlayers = {'O': (2,), 'Pd': (2,), 'Cu': (2,)}

    weights = OrderedDict([('O', OrderedDict([(1, np.matrix([[-2.0, 6.0],
                                                             [3.0, -3.0],
                                                             [1.5, -0.9]])),
                                              (2, np.matrix([[5.5],
                                                             [3.6],
                                                             [1.4]]))])),
                           ('Pd', OrderedDict([(1, np.matrix([[-1.0, 3.0],
                                                              [2.0, 4.2],
                                                              [1.0, -0.7]])),
                                               (2, np.matrix([[4.0],
                                                              [0.5],
                                                              [3.0]]))])),
                           ('Cu', OrderedDict([(1, np.matrix([[0.0, 1.0],
                                                              [-1.0, -2.0],
                                                              [2.5, -1.9]])),
                                               (2, np.matrix([[0.5],
                                                              [1.6],
                                                              [-1.4]]))]))])

    scalings = OrderedDict([('O', OrderedDict([('intercept', -2.3),
                                               ('slope', 4.5)])),
                            ('Pd', OrderedDict([('intercept', 1.6),
                                                ('slope', 2.5)])),
                            ('Cu', OrderedDict([('intercept', -0.3),
                                                ('slope', -0.5)]))])

    fingerprints_range = {"Cu": np.array([[2.8636310860653253,
                                           2.8636310860653253],
                                          [1.5435994865298275,
                                           1.5435994865298275]]),
                          "O": np.array([[2.9409056366723028,
                                          2.972494902604392],
                                         [1.9522542722823606,
                                          4.0720361595017245]]),
                          "Pd": np.array([[2.4629488092411096,
                                           2.6160138774087125],
                                          [0.27127576524253594,
                                           0.5898312261433813]])}

    # Testing pure-python and fortran versions of Gaussian-neural force call
    for fortran in [False, True]:
        for cores in range(1, 4):
            label = 'call-periodic/%s-%i' % (fortran, cores)
            calc = Amp(descriptor=Gaussian(cutoff=4.,
                                           Gs=Gs,
                                           fortran=fortran),
                       model=NeuralNetwork(hiddenlayers=hiddenlayers,
                                           weights=weights,
                                           scalings=scalings,
                                           activation='tanh',
                                           fprange=fingerprints_range,
                                           mode='atom-centered',
                                           fortran=fortran),
                       label=label,
                       dblabel=label,
                       cores=cores)

            predicted_energies = [calc.get_potential_energy(image) for image in
                                  images]

            for image_no in range(len(predicted_energies)):
                diff = abs(predicted_energies[image_no] -
                           correct_energies[image_no])
                assert (diff < 10.**(-14.)), \
                    'The predicted energy of image %i is wrong!' % (
                        image_no + 1)

            predicted_forces = [calc.get_forces(image) for image in images]

            for image_no in range(len(predicted_forces)):
                for index in range(np.shape(predicted_forces[image_no])[0]):
                    for direction in range(
                            np.shape(predicted_forces[image_no])[1]):
                        diff = abs(predicted_forces[image_no][index][
                            direction] -
                            correct_forces[image_no][index][direction])
                        assert (diff < 10.**(-11.)), \
                            'The predicted %i force of atom %i of image' \
                            ' %i is wrong!' % (direction,
                                               index,
                                               image_no + 1)
Esempio n. 14
0
def test():

    ###########################################################################
    # Parameters

    weights = \
        OrderedDict([(1, np.array([[0.14563579, 0.19176385],
                                   [-0.01991609, 0.35873379],
                                   [-0.27988951, 0.03490866],
                                   [0.19195185, 0.43116313],
                                   [0.41035737, 0.02617128],
                                   [-0.13235187, -0.23112657],
                                   [-0.29065111, 0.23865951],
                                   [0.05854897, 0.24249052],
                                   [0.13660673, 0.19288898],
                                   [0.31894165, -0.41831075],
                                   [-0.23522261, -0.24009372],
                                   [-0.14450575, -0.15275409],
                                   [0., 0.]])),
                     (2, np.array([[-0.27415999],
                                   [0.28538579],
                                   [0.]])),
                     (3, np.array([[0.32147131],
                                   [0.]]))])

    scalings = OrderedDict([('intercept', 3.), ('slope', 2.)])

    images = generate_images()

    ###########################################################################
    # Testing pure-python and fortran versions of CartesianNeural on different
    # number of processes

    for fortran in [False, True]:

        calc = Amp(
            descriptor=None,
            regression=NeuralNetwork(hiddenlayers=(2, 1),
                                     weights=weights,
                                     scalings=scalings,
                                     activation='tanh'),
            fortran=fortran,
        )

        predicted_energies = [
            calc.get_potential_energy(image) for image in images
        ]

        for image_no in range(len(predicted_energies)):
            assert (abs(predicted_energies[image_no] -
                        correct_predicted_energies[image_no]) <
                    5 * 10.**(-10.)), \
                'The calculated energy of image %i is wrong!' % (image_no + 1)

        predicted_forces = [calc.get_forces(image) for image in images]

        for image_no in range(len(predicted_forces)):
            for index in range(np.shape(predicted_forces[image_no])[0]):
                for direction in range(3):
                    assert (abs(predicted_forces[image_no][index][direction] -
                                correct_predicted_forces[image_no][index]
                                [direction]) < 5 * 10.**(-10.)), \
                        'The calculated %i force of atom %i of image %i is' \
                        'wrong!' % (direction, index, image_no + 1)
Esempio n. 15
0
def test():
    """Gaussian/Neural numeric-analytic consistency."""
    images = generate_data()
    regressor = Regressor(optimizer='BFGS')

    _G = make_symmetry_functions(type='G2',
                                 etas=[0.05, 5.],
                                 elements=['Cu', 'Pt'])
    _G += make_symmetry_functions(type='G4',
                                  etas=[0.005],
                                  zetas=[1., 4.],
                                  gammas=[1.],
                                  elements=['Cu', 'Pt'])
    Gs = {'Cu': _G, 'Pt': _G}
    calc = Amp(descriptor=Gaussian(Gs=Gs),
               model=NeuralNetwork(
                   hiddenlayers=(2, 1),
                   regressor=regressor,
                   randomseed=42,
               ),
               cores=1)

    step = 0
    for d in [None, 0.00001]:
        for fortran in [True, False]:
            for cores in [1, 2]:
                step += 1
                label = \
                    'numeric_analytic_test/analytic-%s-%i' % (fortran, cores) \
                    if d is None \
                    else 'numeric_analytic_test/numeric-%s-%i' \
                    % (fortran, cores)
                print(label)

                loss = LossFunction(convergence={
                    'energy_rmse': 10**10,
                    'force_rmse': 10**10
                },
                                    d=d)
                calc.set_label(label)
                calc.dblabel = 'numeric_analytic_test/analytic-True-1'
                calc.model.lossfunction = loss
                calc.descriptor.fortran = fortran
                calc.model.fortran = fortran
                calc.cores = cores

                calc.train(images=images, )

                if step == 1:
                    ref_energies = []
                    ref_forces = []
                    for image in images:
                        ref_energies += [calc.get_potential_energy(image)]
                        ref_forces += [calc.get_forces(image)]
                        ref_dloss_dparameters = \
                            calc.model.lossfunction.dloss_dparameters
                else:
                    energies = []
                    forces = []
                    for image in images:
                        energies += [calc.get_potential_energy(image)]
                        forces += [calc.get_forces(image)]
                        dloss_dparameters = \
                            calc.model.lossfunction.dloss_dparameters

                    for image_no in range(2):

                        diff = abs(energies[image_no] - ref_energies[image_no])
                        assert (diff < 10.**(-13.)), \
                            'The calculated value of energy of image %i is ' \
                            'wrong!' % (image_no + 1)

                        for atom_no in range(len(images[0])):
                            for i in range(3):
                                diff = abs(forces[image_no][atom_no][i] -
                                           ref_forces[image_no][atom_no][i])
                                assert (diff < 10.**(-10.)), \
                                    'The calculated %i force of atom %i of ' \
                                    'image %i is wrong!' \
                                    % (i, atom_no, image_no + 1)
                        # Checks analytical and numerical dloss_dparameters
                        for _ in range(len(ref_dloss_dparameters)):
                            diff = abs(dloss_dparameters[_] -
                                       ref_dloss_dparameters[_])
                            assert(diff < 10 ** (-10.)), \
                                'The calculated value of loss function ' \
                                'derivative is wrong!'
    # Checks analytical and numerical forces
    forces = []
    for image in images:
        image.set_calculator(calc)
        forces += [calc.calculate_numerical_forces(image, d=d)]
    for atom_no in range(len(images[0])):
        for i in range(3):
            diff = abs(forces[image_no][atom_no][i] -
                       ref_forces[image_no][atom_no][i])
            print('{:3d} {:1d} {:7.1e}'.format(atom_no, i, diff))
            assert (diff < 10.**(-6.)), \
                'The calculated %i force of atom %i of ' \
                'image %i is wrong! (Diff = %f)' \
                % (i, atom_no, image_no + 1, diff)
Esempio n. 16
0
def periodic_test():
    """Gaussian/tflowNeural periodic."""
    perform, reason = check_perform()
    if not perform:
        print('Skipping this test because {}'.format(reason))
        return

    from amp.model.tflow import NeuralNetwork
    # Making the list of periodic images
    images = [Atoms(symbols='PdOPd',
                    pbc=np.array([True, False, False], dtype=bool),
                    cell=np.array(
                        [[2.,  0.,  0.],
                         [0.,  2.,  0.],
                         [0.,  0.,  2.]]),
                    positions=np.array(
                        [[0.5,  1., 0.5],
                         [1.,  0.5,  1.],
                         [1.5,  1.5,  1.5]])),
              Atoms(symbols='PdO',
                    pbc=np.array([True, True, False], dtype=bool),
                    cell=np.array(
                        [[2.,  0.,  0.],
                         [0.,  2.,  0.],
                            [0.,  0.,  2.]]),
                    positions=np.array(
                        [[0.5,  1., 0.5],
                         [1.,  0.5,  1.]])),
              Atoms(symbols='Cu',
                    pbc=np.array([True, True, False], dtype=bool),
                    cell=np.array(
                        [[1.8,  0.,  0.],
                         [0.,  1.8,  0.],
                            [0.,  0.,  1.8]]),
                    positions=np.array(
                        [[0.,  0., 0.]]))]

    # Correct energies and forces
    correct_energies = [3.8560954326995978, 1.6120748520627273,
                        0.19433107801410093]
    correct_forces = \
        [[[0.14747720528015523, -3.3010645563584973, 3.3008168318984463],
          [0.03333579762326405, 9.050780376599887, -0.42608278400777605],
            [-0.1808130029034193, -5.7497158202413905, -2.8747340478906698]],
            [[6.5035267996045045 * (10.**(-6.)),
              -6.503526799604495 * (10.**(-6.)),
              0.00010834689201069249],
             [-6.5035267996045045 * (10.**(-6.)),
              6.503526799604495 * (10.**(-6.)),
              -0.00010834689201069249]],
            [[0.0, 0.0, 0.0]]]

    # Parameters
    Gs = {'O': [{'type': 'G2', 'element': 'Pd', 'eta': 0.8},
                {'type': 'G4', 'elements': ['O', 'Pd'], 'eta':0.3, 'gamma':0.6,
                 'zeta':0.5}],
          'Pd': [{'type': 'G2', 'element': 'Pd', 'eta': 0.2},
                 {'type': 'G4', 'elements': ['Pd', 'Pd'],
                  'eta':0.9, 'gamma':0.75, 'zeta':1.5}],
          'Cu': [{'type': 'G2', 'element': 'Cu', 'eta': 0.8},
                 {'type': 'G4', 'elements': ['Cu', 'Cu'], 'eta':0.3,
                          'gamma':0.6, 'zeta':0.5}]}

    hiddenlayers = {'O': (2, 1), 'Pd': (2, 1), 'Cu': (2, 1)}

    weights = OrderedDict([('O', OrderedDict([(1, np.matrix([[-2.0, 6.0],
                                                             [3.0, -3.0],
                                                             [1.5, -0.9]])),
                                              (2, np.matrix([[5.5],
                                                             [3.6],
                                                             [1.4]]))])),
                           ('Pd', OrderedDict([(1, np.matrix([[-1.0, 3.0],
                                                              [2.0, 4.2],
                                                              [1.0, -0.7]])),
                                               (2, np.matrix([[4.0],
                                                              [0.5],
                                                              [3.0]]))])),
                           ('Cu', OrderedDict([(1, np.matrix([[0.0, 1.0],
                                                              [-1.0, -2.0],
                                                              [2.5, -1.9]])),
                                               (2, np.matrix([[0.5],
                                                              [1.6],
                                                              [-1.4]]))]))])

    scalings = OrderedDict([('O', OrderedDict([('intercept', -2.3),
                                               ('slope', 4.5)])),
                            ('Pd', OrderedDict([('intercept', 1.6),
                                                ('slope', 2.5)])),
                            ('Cu', OrderedDict([('intercept', -0.3),
                                                ('slope', -0.5)]))])

    fingerprints_range = {"Cu": np.array([[2.8636310860653253,
                                           2.8636310860653253],
                                          [1.5435994865298275,
                                           1.5435994865298275]]),
                          "O": np.array([[2.9409056366723028,
                                          2.972494902604392],
                                         [1.9522542722823606,
                                          4.0720361595017245]]),
                          "Pd": np.array([[2.4629488092411096,
                                           2.6160138774087125],
                                          [0.27127576524253594,
                                           0.5898312261433813]])}

    # Testing pure-python and fortran versions of Gaussian-neural force call
    for fortran in [False, True]:
        for cores in range(1, 4):
            label = 'call-periodic/%s-%i' % (fortran, cores)
            calc = Amp(descriptor=Gaussian(cutoff=4.,
                                           Gs=Gs,
                                           fortran=fortran),
                       model=NeuralNetwork(hiddenlayers=hiddenlayers,
                                           weights=weights,
                                           scalings=scalings,
                                           activation='tanh',
                                           fprange=fingerprints_range,
                                           unit_type="double"),
                       label=label,
                       dblabel=label,
                       cores=cores)

            predicted_energies = [calc.get_potential_energy(image) for image in
                                  images]

            for image_no in range(len(predicted_energies)):
                print(predicted_energies[image_no])
                print(correct_energies[image_no])
                diff = abs(predicted_energies[image_no] -
                           correct_energies[image_no])
                assert (diff < 10.**(-14.)), \
                    'The predicted energy of image %i is wrong!' % (
                        image_no + 1)

            predicted_forces = [calc.get_forces(image) for image in images]

            for image_no in range(len(predicted_forces)):
                print('predicted forces:')
                print(predicted_forces[image_no])
                print('correct forces:')
                print(np.array(correct_forces[image_no]))
                for index in range(np.shape(predicted_forces[image_no])[0]):
                    for direction in range(
                            np.shape(predicted_forces[image_no])[1]):
                        diff = abs(predicted_forces[image_no][index][
                            direction] -
                            correct_forces[image_no][index][direction])
                        assert (diff < 10.**(-11.)), \
                            'The predicted %i force of atom %i of image' \
                            ' %i is wrong!' % (direction,
                                               index,
                                               image_no + 1)
def test():
    images = generate_data(2)
    regressor = Regressor(optimizer='BFGS')

    calc = Amp(descriptor=Gaussian(),
               model=NeuralNetwork(hiddenlayers=(3, 3),
                                   regressor=regressor,),
               cores=1)

    step = 0
    for d in [None, 0.00001]:
        for fortran in [True, False]:
            for cores in [1, 2]:
                step += 1
                label = \
                    'numeric_analytic_test/analytic-%s-%i' % (fortran, cores) \
                    if d is None \
                    else 'numeric_analytic_test/numeric-%s-%i' \
                    % (fortran, cores)
                print(label)

                loss = LossFunction(convergence={'energy_rmse': 10 ** 10,
                                                 'force_rmse': 10 ** 10},
                                    d=d)
                calc.set_label(label)
                calc.dblabel = 'numeric_analytic_test/analytic-True-1'
                calc.model.lossfunction = loss
                calc.descriptor.fortran = fortran
                calc.model.fortran = fortran
                calc.cores = cores

                calc.train(images=images,)

                if step == 1:
                    ref_energies = []
                    ref_forces = []
                    for image in images:
                        ref_energies += [calc.get_potential_energy(image)]
                        ref_forces += [calc.get_forces(image)]
                        ref_dloss_dparameters = \
                            calc.model.lossfunction.dloss_dparameters
                else:
                    energies = []
                    forces = []
                    for image in images:
                        energies += [calc.get_potential_energy(image)]
                        forces += [calc.get_forces(image)]
                        dloss_dparameters = \
                            calc.model.lossfunction.dloss_dparameters

                    for image_no in range(2):

                        diff = abs(energies[image_no] - ref_energies[image_no])
                        assert (diff < 10.**(-13.)), \
                            'The calculated value of energy of image %i is ' \
                            'wrong!' % (image_no + 1)

                        for atom_no in range(6):
                            for i in range(3):
                                diff = abs(forces[image_no][atom_no][i] -
                                           ref_forces[image_no][atom_no][i])
                                assert (diff < 10.**(-10.)), \
                                    'The calculated %i force of atom %i of ' \
                                    'image %i is wrong!' \
                                    % (i, atom_no, image_no + 1)
                        # Checks analytical and numerical dloss_dparameters
                        for _ in range(len(ref_dloss_dparameters)):
                            diff = abs(dloss_dparameters[_] -
                                       ref_dloss_dparameters[_])
                            assert(diff < 10 ** (-10.)), \
                                'The calculated value of loss function ' \
                                'derivative is wrong!'
    # Checks analytical and numerical forces
    forces = []
    for image in images:
        image.set_calculator(calc)
        forces += [calc.calculate_numerical_forces(image, d=d)]
    for atom_no in range(6):
        for i in range(3):
            diff = abs(forces[image_no][atom_no][i] -
                       ref_forces[image_no][atom_no][i])
            assert (diff < 10.**(-9.)), \
                'The calculated %i force of atom %i of ' \
                'image %i is wrong!' % (i, atom_no, image_no + 1)
def non_periodic_test():

    # Making the list of non-periodic images
    images = [Atoms(symbols='PdOPd2',
                    pbc=np.array([False, False, False], dtype=bool),
                    cell=np.array(
                        [[1.,  0.,  0.],
                         [0.,  1.,  0.],
                            [0.,  0.,  1.]]),
                    positions=np.array(
                        [[0.,  0.,  0.],
                         [0.,  2.,  0.],
                            [0.,  0.,  3.],
                            [1.,  0.,  0.]])),
              Atoms(symbols='PdOPd2',
                    pbc=np.array([False, False, False], dtype=bool),
                    cell=np.array(
                        [[1.,  0.,  0.],
                         [0.,  1.,  0.],
                            [0.,  0.,  1.]]),
                    positions=np.array(
                        [[0.,  1.,  0.],
                         [1.,  2.,  1.],
                            [-1.,  1.,  2.],
                            [1.,  3.,  2.]])),
              Atoms(symbols='PdO',
                    pbc=np.array([False, False, False], dtype=bool),
                    cell=np.array(
                        [[1.,  0.,  0.],
                         [0.,  1.,  0.],
                         [0.,  0.,  1.]]),
                    positions=np.array(
                        [[2.,  1., -1.],
                         [1.,  2.,  1.]])),
              Atoms(symbols='Pd2O',
                    pbc=np.array([False, False, False], dtype=bool),
                    cell=np.array(
                        [[1.,  0.,  0.],
                         [0.,  1.,  0.],
                         [0.,  0.,  1.]]),
                    positions=np.array(
                        [[-2., -1., -1.],
                         [1.,  2.,  1.],
                         [3.,  4.,  4.]])),
              Atoms(symbols='Cu',
                    pbc=np.array([False, False, False], dtype=bool),
                    cell=np.array(
                        [[1.,  0.,  0.],
                         [0.,  1.,  0.],
                         [0.,  0.,  1.]]),
                    positions=np.array(
                        [[0.,  0.,  0.]]))]

    # Correct energies and forces
    correct_energies = [14.231186811226152, 14.327219917287948,
                        5.5742510565528285, 9.41456771216968,
                        -0.5019297954597407]
    correct_forces = \
        [[[-0.05095024246182649, -0.10709193432146558, -0.09734321482638622],
          [-0.044550772904033635, 0.2469763195486647, -0.07617425912869778],
            [-0.02352490951707703, -0.050782839419131864, 0.24409220250631508],
            [0.11902592488293715, -0.08910154580806727, -0.07057472855123109]],
            [[-0.024868720575099375, -0.07417891957113862,
              -0.12121240797223251],
             [0.060156158438252574, 0.017517013378773042,
              -0.020047135079325505],
             [-0.10901144291312388, -0.06671262448352767, 0.06581556263014315],
             [0.07372400504997068, 0.12337453067589325, 0.07544398042141486]],
            [[0.10151747265164626, -0.10151747265164626, -0.20303494530329252],
             [-0.10151747265164626, 0.10151747265164626, 0.20303494530329252]],
            [[-0.00031177673224312745, -0.00031177673224312745,
              -0.0002078511548287517],
             [0.004823209772264884, 0.004823209772264884,
              0.006975000714861393],
             [-0.004511433040021756, -0.004511433040021756,
              -0.006767149560032641]],
            [[0.0, 0.0, 0.0]]]

    # Parameters
    Gs = {'O': [{'type': 'G2', 'element': 'Pd', 'eta': 0.8},
                {'type': 'G4', 'elements': [
                    'Pd', 'Pd'], 'eta':0.2, 'gamma':0.3, 'zeta':1},
                {'type': 'G4', 'elements': ['O', 'Pd'], 'eta':0.3, 'gamma':0.6,
                 'zeta':0.5}],
          'Pd': [{'type': 'G2', 'element': 'Pd', 'eta': 0.2},
                 {'type': 'G4', 'elements': ['Pd', 'Pd'],
                  'eta':0.9, 'gamma':0.75, 'zeta':1.5},
                 {'type': 'G4', 'elements': ['O', 'Pd'], 'eta':0.4,
                  'gamma':0.3, 'zeta':4}],
          'Cu': [{'type': 'G2', 'element': 'Cu', 'eta': 0.8},
                 {'type': 'G4', 'elements': ['Cu', 'O'],
                  'eta':0.2, 'gamma':0.3, 'zeta':1},
                 {'type': 'G4', 'elements': ['Cu', 'Cu'], 'eta':0.3,
                  'gamma':0.6, 'zeta':0.5}]}

    hiddenlayers = {'O': (2,), 'Pd': (2,), 'Cu': (2,)}

    weights = OrderedDict([('O', OrderedDict([(1, np.matrix([[-2.0, 6.0],
                                                             [3.0, -3.0],
                                                             [1.5, -0.9],
                                                             [-2.5, -1.5]])),
                                              (2, np.matrix([[5.5],
                                                             [3.6],
                                                             [1.4]]))])),
                           ('Pd', OrderedDict([(1, np.matrix([[-1.0, 3.0],
                                                              [2.0, 4.2],
                                                              [1.0, -0.7],
                                                              [-3.0, 2.0]])),
                                               (2, np.matrix([[4.0],
                                                              [0.5],
                                                              [3.0]]))])),
                           ('Cu', OrderedDict([(1, np.matrix([[0.0, 1.0],
                                                              [-1.0, -2.0],
                                                              [2.5, -1.9],
                                                              [-3.5, 0.5]])),
                                               (2, np.matrix([[0.5],
                                                              [1.6],
                                                              [-1.4]]))]))])

    scalings = OrderedDict([('O', OrderedDict([('intercept', -2.3),
                                               ('slope', 4.5)])),
                            ('Pd', OrderedDict([('intercept', 1.6),
                                                ('slope', 2.5)])),
                            ('Cu', OrderedDict([('intercept', -0.3),
                                                ('slope', -0.5)]))])

    fingerprints_range = {"Cu": np.array([[0.0, 0.0], [0.0, 0.0], [0.0, 0.0]]),
                          "O": np.array([[0.2139617720858539,
                                          2.258090276328769],
                                         [0.0, 1.085656080548734],
                                         [0.0, 0.0]]),
                          "Pd": np.array([[0.0, 1.4751761770313006],
                                          [0.0, 0.28464992134267897],
                                          [0.0, 0.20167521020630502]])}

    # Testing pure-python and fortran versions of Gaussian-neural force call
    for fortran in [False, True]:
        for cores in range(1, 6):
            label = 'call-nonperiodic/%s-%i' % (fortran, cores)
            calc = Amp(descriptor=Gaussian(cutoff=6.5,
                                           Gs=Gs,
                                           fortran=fortran),
                       model=NeuralNetwork(hiddenlayers=hiddenlayers,
                                           weights=weights,
                                           scalings=scalings,
                                           activation='sigmoid',
                                           fprange=fingerprints_range,
                                           mode='atom-centered',
                                           fortran=fortran),
                       label=label,
                       dblabel=label,
                       cores=cores)

            predicted_energies = [calc.get_potential_energy(image) for image in
                                  images]

            for image_no in range(len(predicted_energies)):
                diff = abs(predicted_energies[image_no] -
                           correct_energies[image_no])
                assert (diff < 10.**(-15.)), \
                    'The predicted energy of image %i is wrong!' % (
                        image_no + 1)

            predicted_forces = [calc.get_forces(image) for image in images]

            for image_no in range(len(predicted_forces)):
                for index in range(np.shape(predicted_forces[image_no])[0]):
                    for direction in range(
                            np.shape(predicted_forces[image_no])[1]):
                        diff = abs(predicted_forces[image_no][index][
                            direction] -
                            correct_forces[image_no][index][direction])
                        assert (diff < 10.**(-15.)), \
                            'The predicted %i force of atom %i of image %i ' \
                            'is wrong!' % (direction, index, image_no + 1)