def cubic_jacobian_polynomial(nodes):
    r"""Compute the Jacobian determinant of a cubic surface.

    .. note::

       This is used **only** by :meth:`Surface._compute_valid` (which is
       in turn used to compute / cache the :attr:`Surface.is_valid`
       property).

    Converts :math:`\det(J(s, t))` to a polynomial on the reference
    triangle and represents it as a surface object.

    .. note::

       This assumes that ``nodes`` is ``2 x 10`` but doesn't verify this.
       (However, the right multiplication by ``_CUBIC_JACOBIAN_HELPER``
       would fail if ``nodes`` wasn't ``R x 10`` and then the ensuing
       determinants would fail if there weren't 2 rows.)

    Args:
        nodes (numpy.ndarray): A 2 x 10 array of nodes in a surface.

    Returns:
        numpy.ndarray: 1 x 15 array, coefficients in Bernstein basis.
    """
    # First evaluate the Jacobian at each of the 15 nodes
    # in the quartic triangle.
    jac_parts = _helpers.matrix_product(nodes, _CUBIC_JACOBIAN_HELPER)
    jac_at_nodes = np.empty((1, 15), order="F")
    jac_at_nodes[0, 0] = two_by_two_det(jac_parts[:, :2])
    jac_at_nodes[0, 1] = two_by_two_det(jac_parts[:, 2:4])
    jac_at_nodes[0, 2] = two_by_two_det(jac_parts[:, 4:6])
    jac_at_nodes[0, 3] = two_by_two_det(jac_parts[:, 6:8])
    jac_at_nodes[0, 4] = two_by_two_det(jac_parts[:, 8:10])
    jac_at_nodes[0, 5] = two_by_two_det(jac_parts[:, 10:12])
    jac_at_nodes[0, 6] = two_by_two_det(jac_parts[:, 12:14])
    jac_at_nodes[0, 7] = two_by_two_det(jac_parts[:, 14:16])
    jac_at_nodes[0, 8] = two_by_two_det(jac_parts[:, 16:18])
    jac_at_nodes[0, 9] = two_by_two_det(jac_parts[:, 18:20])
    jac_at_nodes[0, 10] = two_by_two_det(jac_parts[:, 20:22])
    jac_at_nodes[0, 11] = two_by_two_det(jac_parts[:, 22:24])
    jac_at_nodes[0, 12] = two_by_two_det(jac_parts[:, 24:26])
    jac_at_nodes[0, 13] = two_by_two_det(jac_parts[:, 26:28])
    jac_at_nodes[0, 14] = two_by_two_det(jac_parts[:, 28:])
    # Convert the nodal values to the Bernstein basis...
    bernstein = _helpers.matrix_product(jac_at_nodes, _QUARTIC_TO_BERNSTEIN)
    bernstein /= _QUARTIC_BERNSTEIN_FACTOR
    return bernstein
r"""Compute the Jacobian determinant of a cubic surface.

    .. note::

       This is used **only** by :meth:`Surface._compute_valid` (which is
       in turn used to compute / cache the :attr:`Surface.is_valid`
       property).

    Converts :math:`\det(J(s, t))` to a polynomial on the reference
    triangle and represents it as a surface object.

    .. note::

       This assumes that ``nodes`` is ``2 x 10`` but doesn't verify this.
       (However, the right multiplication by ``_CUBIC_JACOBIAN_HELPER``
       would fail if ``nodes`` wasn't ``R x 10`` and then the ensuing
       determinants would fail if there weren't 2 rows.)

    Args:
        nodes (numpy.ndarray): A 2 x 10 array of nodes in a surface.

    Returns:
        numpy.ndarray: 1 x 15 array, coefficients in Bernstein basis.