Here is my first attempt, however the SGD optimizer doesn’t like taking a tensor (where the tensor is the values I’m trying to optimise), failing with “no matching function for call to ‘torch::optim::SGD::SGD(at::Tensor&, double)”
torch::Tensor dynamic_parameters = torch::zeros({1}, torch::dtype(torch::kFloat64).requires_grad(true));

{
    torch::NoGradGuard guard;
    dynamic_parameters[0] = initial_guess;
}

torch::optim::SGD optimizer(dynamic_parameters, /*lr=*/0.01);

#define N_STEPS 20

for (int s = 0; s < N_STEPS; s ++)
{
    torch::Tensor result = torch::zeros({1}, torch::dtype(torch::kFloat64).requires_grad(true));

    torch::Tensor magnitudes = torch::zeros({N_V}, torch::dtype(torch::kFloat64).requires_grad(false));

    magnitudes += gState.magnitudes_ones_tensor * dynamic_parameters[0];

    torch::Tensor synth = gState.dots * magnitudes;

    torch::Tensor differences = torch::abs(real - synth);

    result[0] = torch::sum(differences);

    torch::Tensor loss = torch::nll_loss(result, prediction);

    loss.backward();

    optimizer.step();
}