(
    content,
    expand_symmetries,
    expand_symmetries_points_only,
    scheme_from_dict,
    get_evaluator,
)
return d, out.fun, np.linalg.cond(A)
Compute the weights from the points via a least-squares problem. Only the point
    coordinates are variables.
Compute the weights from the points via a least-squares problem. Only the point
    coordinates are variables.
Compute the weights from the points via a least - squares problem . Only the point coordinates are variables .
def _optimize(
    content,
    expand_symmetries,
    expand_symmetries_points_only,
    scheme_from_dict,
    get_evaluator,
):
    """Compute the weights from the points via a least-squares problem. Only the point
    coordinates are variables.
    """
    import numpy as np
    from scipy.optimize import minimize

    degree = content["degree"]
    keys = list(content["data"].keys())
    num_symm = [len(item[0]) for item in content["data"].values()]

    def x_to_dict(x):
        # convert x to dictionary (without weights)
        x_split = np.split(x, splits)
        vals = [item.reshape(shape) for item, shape in zip(x_split, shapes)]
        d = dict(zip(keys, vals))
        return d

    def get_w_from_x(x):
        d = x_to_dict(x)
        points, len_symm = expand_symmetries_points_only(d, dim=2)

        if np.any(np.isnan(points)):
            # return some "large" residual value
            return None, None, None, 1.0

        # evaluate all orthogonal polynomials up to `degree` at all points
        evaluator = get_evaluator(points)
        A2 = np.concatenate([next(evaluator) for _ in range(degree + 1)])

        assert sum(a * b for a, b in zip(len_symm, num_symm)) == A2.shape[1]

        # sum up all columns which belong to the same weight
        k = 0
        sums = []
        for lsym, nsym in zip(len_symm, num_symm):
            for i in range(nsym):
                sums.append(np.sum(A2[:, k + i : k + lsym * nsym : nsym], axis=1))
            k += lsym * nsym

        A = np.column_stack(sums)

        # The exact values are 0 except for the first entry
        b = np.zeros(A.shape[0])
        b[0] = evaluator.int_p0
        # b[0] /= np.pi  # necessary for S2

        w, res, rank, s = np.linalg.lstsq(A, b, rcond=None)

        # spherical harmonics (for u3) are complex-valued
        assert np.all(np.abs(w.imag) < 1.0e-15)
        w = w.real

        if rank < min(A.shape):
            # return some "large" residual value
            return None, None, None, 1.0

        return A, b, w, np.sqrt(res[0])

    def f(x):
        _, _, _, res = get_w_from_x(x)
        # print(f"f(x) = {res:.6e}")
        return res

    keys = list(content["data"].keys())
    values = list(content["data"].values())

    values_without_weights = [val[1:] for val in values]
    shapes = [np.array(val).shape for val in values_without_weights]
    sizes = [np.array(val).size for val in values_without_weights]
    splits = np.cumsum(sizes)[:-1]

    # collect and concatenate all point coords
    x0 = np.concatenate([np.array(val).flat for val in values_without_weights])

    # TODO check initial residual with original weights
    r0 = f(x0)

    out = minimize(f, x0, method="Nelder-Mead", tol=1.0e-17)

    # Don't fail on `not out.success`. It could be because of
    # ```
    # Maximum number of function evaluations has been exceeded
    # ```
    # but the scheme could still have improved.

    # out.fun == f(out.x) exactly
    if r0 <= out.fun:
        raise RuntimeError("Optimization couldn't improve scheme.")

    # compute max(err)
    A, b, w, _ = get_w_from_x(out.x)
    # assert A is not None
    # max_res = np.max(np.abs(A @ w - b))

    # Compute max_res exactly like in the tests
    d = x_to_dict(out.x)
    # prepend weights
    k = 0
    for key, value in d.items():
        if len(value.shape) == 1:
            n = 1
            d[key] = [[w[k]]]
        else:
            n = value.shape[1]
            d[key] = np.column_stack([w[k : k + n], value.T]).T
        k += n
    # content["data"] = d
    # scheme = scheme_from_dict(content)
    # max_res = max(scheme.compute_residuals(degree))

    # print(max_res)

    return d, out.fun, np.linalg.cond(A)
def _optimize ( content , expand_symmetries , expand_symmetries_points_only , scheme_from_dict , get_evaluator , ) : import numpy as np from scipy . optimize import minimize degree = content [ "degree" ] keys = list ( content [ "data" ] . keys ( ) ) num_symm = [ len ( item [ 0 ] ) for item in content [ "data" ] . values ( ) ] def x_to_dict ( x ) : # convert x to dictionary (without weights) x_split = np . split ( x , splits ) vals = [ item . reshape ( shape ) for item , shape in zip ( x_split , shapes ) ] d = dict ( zip ( keys , vals ) ) return d def get_w_from_x ( x ) : d = x_to_dict ( x ) points , len_symm = expand_symmetries_points_only ( d , dim = 2 ) if np . any ( np . isnan ( points ) ) : # return some "large" residual value return None , None , None , 1.0 # evaluate all orthogonal polynomials up to `degree` at all points evaluator = get_evaluator ( points ) A2 = np . concatenate ( [ next ( evaluator ) for _ in range ( degree + 1 ) ] ) assert sum ( a * b for a , b in zip ( len_symm , num_symm ) ) == A2 . shape [ 1 ] # sum up all columns which belong to the same weight k = 0 sums = [ ] for lsym , nsym in zip ( len_symm , num_symm ) : for i in range ( nsym ) : sums . append ( np . sum ( A2 [ : , k + i : k + lsym * nsym : nsym ] , axis = 1 ) ) k += lsym * nsym A = np . column_stack ( sums ) # The exact values are 0 except for the first entry b = np . zeros ( A . shape [ 0 ] ) b [ 0 ] = evaluator . int_p0 # b[0] /= np.pi  # necessary for S2 w , res , rank , s = np . linalg . lstsq ( A , b , rcond = None ) # spherical harmonics (for u3) are complex-valued assert np . all ( np . abs ( w . imag ) < 1.0e-15 ) w = w . real if rank < min ( A . shape ) : # return some "large" residual value return None , None , None , 1.0 return A , b , w , np . sqrt ( res [ 0 ] ) def f ( x ) : _ , _ , _ , res = get_w_from_x ( x ) # print(f"f(x) = {res:.6e}") return res keys = list ( content [ "data" ] . keys ( ) ) values = list ( content [ "data" ] . values ( ) ) values_without_weights = [ val [ 1 : ] for val in values ] shapes = [ np . array ( val ) . shape for val in values_without_weights ] sizes = [ np . array ( val ) . size for val in values_without_weights ] splits = np . cumsum ( sizes ) [ : - 1 ] # collect and concatenate all point coords x0 = np . concatenate ( [ np . array ( val ) . flat for val in values_without_weights ] ) # TODO check initial residual with original weights r0 = f ( x0 ) out = minimize ( f , x0 , method = "Nelder-Mead" , tol = 1.0e-17 ) # Don't fail on `not out.success`. It could be because of # ``` # Maximum number of function evaluations has been exceeded # ``` # but the scheme could still have improved. # out.fun == f(out.x) exactly if r0 <= out . fun : raise RuntimeError ( "Optimization couldn't improve scheme." ) # compute max(err) A , b , w , _ = get_w_from_x ( out . x ) # assert A is not None # max_res = np.max(np.abs(A @ w - b)) # Compute max_res exactly like in the tests d = x_to_dict ( out . x ) # prepend weights k = 0 for key , value in d . items ( ) : if len ( value . shape ) == 1 : n = 1 d [ key ] = [ [ w [ k ] ] ] else : n = value . shape [ 1 ] d [ key ] = np . column_stack ( [ w [ k : k + n ] , value . T ] ) . T k += n # content["data"] = d # scheme = scheme_from_dict(content) # max_res = max(scheme.compute_residuals(degree)) # print(max_res) return d , out . fun , np . linalg . cond ( A )