def MinimizeTrace(u, alpha, bc, sqrt_relax=1e-16):
    # Compute the tensor decompositions
    D = MakeD(alpha)
    theta, sb = AnglesAndSuperbases(D)
    theta = np.array([theta[:-1], theta[1:]])

    # Compute the second order differences in the direction orthogonal to the superbase
    sb_rotated = np.array([-sb[1], sb[0]])
    d2u = bc.Diff2(u, sb_rotated)
    d2u[..., bc.not_interior] = 0.  # Placeholder values to silent NaNs

    # Compute the coefficients of the tensor decompositions
    sb1, sb2 = np.roll(sb, 1, axis=1), np.roll(sb, 2, axis=1)
    sb1, sb2 = (e.reshape((2, 3, 1) + sb.shape[2:]) for e in (sb1, sb2))
    D = D.reshape((2, 2, 1, 3, 1) + D.shape[3:])
    # Axes of D are space,space,index of superbase element, index of D, index of superbase, and possibly shape of u
    scals = lp.dot_VAV(sb1, D, sb2)

    # Compute the coefficients of the trigonometric polynomial
    scals, theta = (bc.as_field(e) for e in (scals, theta))
    coefs = -lp.dot_VV(scals, np.expand_dims(d2u, axis=1))

    # Optimality condition for the trigonometric polynomial in the interior
    value = coefs[0] - np.sqrt(
        np.maximum(coefs[1]**2 + coefs[2]**2, sqrt_relax))
    coefs_ = np.array(coefs)  # removed AD information
    angle = np.arctan2(-coefs_[2], -coefs_[1]) / 2.
    angle[angle < 0] += np.pi

    # Boundary conditions for the trigonometric polynomial minimization
    mask = np.logical_not(np.logical_and(theta[0] <= angle, angle <= theta[1]))
    t, c = theta[:, mask], coefs[:, mask]
    value[mask], amin_t = ad.min_argmin(c[0] + c[1] * np.cos(2 * t) +
                                        c[2] * np.sin(2 * t),
                                        axis=0)

    # Minimize over superbases
    value, amin_sb = ad.min_argmin(value, axis=0)

    # Record the optimal angles for future use
    angle[mask] = np.take_along_axis(t, np.expand_dims(amin_t, axis=0),
                                     axis=0).squeeze(axis=0)  # Min over bc
    angle = np.take_along_axis(angle, np.expand_dims(amin_sb, axis=0),
                               axis=0)  # Min over superbases

    return value, angle
Example #2
0
def SchemeMALBR_OptInner(u,SB,bc,oracle=None):
    # If the active superbases are known, then take only these
    if not(oracle is None):
        SB = np.take_along_axis(SB,np.broadcast_to(oracle,SB.shape[:2]+(1,)+oracle.shape),axis=2)
                
    d2u = bc.Diff2(u,SB)
    d2u[...,bc.not_interior] = 0. # Placeholder value to silent NaN warnings
    # Evaluate the complex non-linear function using dense - sparse composition
    result = ad.apply(MALBR_H,d2u,shape_bound=u.shape)
    
    return ad.min_argmin(result,axis=0)
def SchemeSampling_OptInner(u, diffs, bc, oracle=None):
    # Select the active tensors, if they are known
    if not (oracle is None):
        diffs = np.take_along_axis(diffs,
                                   np.broadcast_to(
                                       oracle,
                                       diffs.shape[:2] + (1, ) + oracle.shape),
                                   axis=2)

    print("Has AD information :", ad.is_ad(u),
          ". Number active tensors per point :", diffs.shape[2])

    # Tensor decomposition
    coefs, offsets = Selling.Decomposition(diffs)

    # Return the minimal value, and the minimizing index
    return ad.min_argmin(lp.dot_VV(coefs, bc.Diff2(u, offsets)), axis=0)