Beispiel #1
0
mass = den.totalMass()
data0 = numpy.ones((len(initcond), 1))

# discretized density profile to be used as the density constraint
rhs1 = target1(den)

# data2 is kinematic data: for each orbit (row) it contains
# Ngrid values of rho sigma_r^2, then the same number of values of rho sigma_t^2;
# we combine them into a single array of Ngrid values that enforce isotropy (sigma_t^2 - 2 sigma_r^2 = 0)
Ngrid = len(target2) // 2
datak = 2 * data2[:, :Ngrid] - data2[:, Ngrid:]
rhs2 = numpy.zeros(Ngrid)

# solve the matrix equation for orbit weights
weights = agama.solveOpt(matrix=(data0.T, data1.T, datak.T), rhs=([mass], rhs1, rhs2), \
    rpenl=([numpy.inf], numpy.ones_like(rhs1), numpy.ones_like(rhs2)), \
    xpenq=numpy.ones(len(initcond))*0.1 )

# check if all constraints were satisfied
delta1 = data1.T.dot(weights) - rhs1
for i, d in enumerate(delta1):
    if abs(d) > 1e-8:
        print("DensityConstraint %i not satisfied: %s, val=%.4g, rel.err=%.4g" % \
        (i, target1[i], rhs1[i], d / rhs1[i]))
delta2 = datak.T.dot(weights)
for i, d in enumerate(delta2):
    if abs(d) > 1e-8: print("KinemConstraint %i not satisfied: %.4g" % (i, d))

# export an N-body model
nbody = 100000
status, result = agama.sampleOrbitLibrary(nbody, trajs, weights)
def runComponent(comp, pot):
    """
    run the orbit integration, optimization, and construction of an N-body model
    for a given component of the Schwarzschild model
    """
    if hasattr(comp, 'trajsize'):
        result = agama.orbit(potential=pot,
                             ic=comp.ic,
                             time=comp.inttime,
                             Omega=comp.Omega,
                             targets=comp.targets,
                             trajsize=comp.trajsize)
        traj = result[-1]
    else:
        result = agama.orbit(potential=pot,
                             ic=comp.ic,
                             time=comp.inttime,
                             Omega=comp.Omega,
                             targets=comp.targets)
        traj = None
    if type(result) == numpy.array: result = (result, )
    # targets[0] is density, targets[1], if provided, is kinematics
    matrix = list()
    rhs = list()
    rpenl = list()
    mass = comp.density.totalMass()
    # density constraints
    matrix.append(result[0].T)
    rhs.append(comp.targets[0](comp.density))
    avgrhs = mass / len(rhs[0])  # typical magnitude of density constraints
    rpenl.append(numpy.ones_like(rhs[0]) / avgrhs)
    # kinematic constraints
    if len(comp.targets) == 2 and hasattr(comp, 'beta'):
        numrow = len(comp.targets[1]) // 2
        matrix.append(result[1].T[0:numrow] * 2 * (1 - comp.beta) -
                      result[1].T[numrow:2 * numrow])
        rhs.append(numpy.zeros(numrow))
        rpenl.append(numpy.ones(numrow))
    # total mass constraint
    matrix.append(numpy.ones((len(comp.ic), 1)).T)
    rhs.append(numpy.array([mass]))
    rpenl.append(numpy.array([numpy.inf]))
    # regularization (penalty for unequal weights)
    avgweight = mass / len(comp.ic)
    xpenq = numpy.ones(len(comp.ic)) / avgweight**2 / len(comp.ic) * 0.1

    # solve the linear equation for weights
    weights = agama.solveOpt(matrix=matrix, rhs=rhs, rpenl=rpenl, xpenq=xpenq)

    # check for any outstanding constraints
    for t in range(len(matrix)):
        delta = matrix[t].dot(weights) - rhs[t]
        norm = 1e-4 * abs(rhs[t]) + 1e-8
        for c, d in enumerate(delta):
            if abs(d) > norm[c]:
                print("Constraint %i:%i not satisfied: %s, val=%.4g, dif=%.4g" % \
                (t, c, comp.targets[t][c], rhs[t][c], d))
    print("Entropy: %f, # of useful orbits: %i / %i" %\
        ( -sum(weights * numpy.log(weights+1e-100)) / mass + numpy.log(avgweight), \
        len(numpy.where(weights >= avgweight)[0]), len(comp.ic)))

    # create an N-body model if needed
    if hasattr(comp, 'nbody'):
        status, particles = agama.sampleOrbitLibrary(comp.nbody, traj, weights)
        if not status:
            indices, trajsizes = particles
            print("reintegrating %i orbits; max # of sampling points is %i" %
                  (len(indices), max(trajsizes)))
            traj[indices] = agama.orbit(potential=pot, ic=comp.ic[indices], \
                time=comp.inttime[indices], trajsize=trajsizes)
            status, particles = agama.sampleOrbitLibrary(
                comp.nbody, traj, weights)
            if not status: print("Failed to produce output N-body model")
        comp.nbodymodel = particles

    # output
    comp.weights = weights
    comp.densitydata = result[0]
    if len(comp.targets) >= 2: comp.kinemdata = result[1]
    if not traj is None: comp.traj = traj
data, trajs = agama.orbit(potential=pot,
                          ic=initcond,
                          time=inttimes,
                          trajsize=100,
                          targets=target)

# assemble the matrix equation which contains two blocks:
# total mass, discretized density

# a single value for the total mass constraint, each orbit contributes 1 to it
mass = potstars.totalMass()
data0 = numpy.ones((len(initcond), 1))

# solve the matrix equation for orbit weights
weights = agama.solveOpt(matrix=(data0.T, data.T),
                         rhs=([mass], rhs),
                         rpenl=([numpy.inf], numpy.ones(len(rhs)) * numpy.inf),
                         xpenq=numpy.ones(len(initcond)))

#numpy.savetxt('orbits', numpy.column_stack((initcond, weights, inttimes))[numpy.argsort(inttimes)], '%g')

# export an N-body model
nbody = 100000
status, result = agama.sampleOrbitLibrary(nbody, trajs, weights)
if not status:
    # this may occur if there was not enough recorded trajectory points for some high-weight orbits:
    # in this case their indices and the required numbers of points are returned in the result tuple
    indices, trajsizes = result
    print("reintegrating %i orbits; max # of sampling points is %i" %
          (len(indices), max(trajsizes)))
    trajs[indices] = agama.orbit(potential=pot, ic=initcond[indices], time=inttimes[indices], \
        trajsize=trajsizes)