def ios16_lut_params_to_ios18(lut_params: LutParamsIos16) -> LutParams:
    """
    The iOS18 constexpr_lut_to_dense no longer accepts `shape` param. We need to convert the iOS16
    params to the format acceptable by the iOS18 op.
    """
    num_palettes = lut_params.lut.shape[0]
    nbits = int(math.log2(num_palettes))
    if 2**nbits != num_palettes:
        raise AssertionError(
            f"Invalid number of palettes in lut_params. It should be 2**nbits, but got {num_palettes}"
        )
    # Notice that the indices in iOS16 is packed, so we need to unpack first.
    unpacked_indices = restore_elements_from_packed_bits(
        lut_params.indices, nbits, np.prod(lut_params.shape)
    )
    indices = unpacked_indices.reshape(lut_params.shape).astype(
        types.type_mapping.string_to_nptype(f"uint{nbits}")
    )
    lut_shape = [1] * len(lut_params.shape) + [num_palettes, 1]
    lut = lut_params.lut.reshape(lut_shape)
    return LutParams(indices=indices, lut=lut, vector_axis=None)

    The iOS18 constexpr_lut_to_dense no longer accepts `shape` param. We need to convert the iOS16
    params to the format acceptable by the iOS18 op.
    
coremltools/optimize/_utils.py