# Path: umap/utils.py
# @numba.njit("i4(i8[:])")
# def tau_rand_int(state):
#     """A fast (pseudo)-random number generator.
# 
#     Parameters
#     ----------
#     state: array of int64, shape (3,)
#         The internal state of the rng
# 
#     Returns
#     -------
#     A (pseudo)-random int32 value
#     """
#     state[0] = (((state[0] & 4294967294) << 12) & 0xFFFFFFFF) ^ (
#         (((state[0] << 13) & 0xFFFFFFFF) ^ state[0]) >> 19
#     )
#     state[1] = (((state[1] & 4294967288) << 4) & 0xFFFFFFFF) ^ (
#         (((state[1] << 2) & 0xFFFFFFFF) ^ state[1]) >> 25
#     )
#     state[2] = (((state[2] & 4294967280) << 17) & 0xFFFFFFFF) ^ (
#         (((state[2] << 3) & 0xFFFFFFFF) ^ state[2]) >> 11
#     )
# 
#     return state[0] ^ state[1] ^ state[2]


import numpy as np
import numba
import umap.distances as dist
from umap.utils import tau_rand_int
from tqdm.auto import tqdm

            current = head_embedding[j]
            other = tail_embedding[k]

            dist_output, grad_dist_output = output_metric(
                current, other, *output_metric_kwds
            )
            _, rev_grad_dist_output = output_metric(other, current, *output_metric_kwds)

            if dist_output > 0.0:
                w_l = pow((1 + a * pow(dist_output, 2 * b)), -1)
            else:
                w_l = 1.0
            grad_coeff = 2 * b * (w_l - 1) / (dist_output + 1e-6)

            for d in range(dim):
                grad_d = clip(grad_coeff * grad_dist_output[d])

                current[d] += grad_d * alpha
                if move_other:
                    grad_d = clip(grad_coeff * rev_grad_dist_output[d])
                    other[d] += grad_d * alpha

            epoch_of_next_sample[i] += epochs_per_sample[i]

            n_neg_samples = int(
                (n - epoch_of_next_negative_sample[i]) / epochs_per_negative_sample[i]
            )

            for p in range(n_neg_samples):

# Path: umap/utils.py
# @numba.njit("i4(i8[:])")
# def tau_rand_int(state):
#     """A fast (pseudo)-random number generator.
# 
#     Parameters
#     ----------
#     state: array of int64, shape (3,)
#         The internal state of the rng
# 
#     Returns
#     -------
#     A (pseudo)-random int32 value
#     """
#     state[0] = (((state[0] & 4294967294) << 12) & 0xFFFFFFFF) ^ (
#         (((state[0] << 13) & 0xFFFFFFFF) ^ state[0]) >> 19
#     )
#     state[1] = (((state[1] & 4294967288) << 4) & 0xFFFFFFFF) ^ (
#         (((state[1] << 2) & 0xFFFFFFFF) ^ state[1]) >> 25
#     )
#     state[2] = (((state[2] & 4294967280) << 17) & 0xFFFFFFFF) ^ (
#         (((state[2] << 3) & 0xFFFFFFFF) ^ state[2]) >> 11
#     )
# 
#     return state[0] ^ state[1] ^ state[2]


# Path: umap/layouts.py
import numpy as np
import numba
import umap.distances as dist
from umap.utils import tau_rand_int
from tqdm.auto import tqdm


            current = head_embedding[j]
            other = tail_embedding[k]

            dist_output, grad_dist_output = output_metric(
                current, other, *output_metric_kwds
            )
            _, rev_grad_dist_output = output_metric(other, current, *output_metric_kwds)

            if dist_output > 0.0:
                w_l = pow((1 + a * pow(dist_output, 2 * b)), -1)
            else:
                w_l = 1.0
            grad_coeff = 2 * b * (w_l - 1) / (dist_output + 1e-6)

            for d in range(dim):
                grad_d = clip(grad_coeff * grad_dist_output[d])

                current[d] += grad_d * alpha
                if move_other:
                    grad_d = clip(grad_coeff * rev_grad_dist_output[d])
                    other[d] += grad_d * alpha

            epoch_of_next_sample[i] += epochs_per_sample[i]

            n_neg_samples = int(
                (n - epoch_of_next_negative_sample[i]) / epochs_per_negative_sample[i]
            )

            for p in range(n_neg_samples):

                k = tau_rand_int(rng_state) % n_vertices