def endPointGradient(self, testGradient=False):
        rg, N, T = self.getSimData()
        interp_loc = self.xt[:,:,T-1].copy()

        (interp_target, d_interp) = kernelMatrix_fort.applyk_and_diff( \
                    interp_loc, rg.nodes, self.dual_target,
                    self.khs, self.kho, self.rg.num_nodes)

        diff = self.m[:,T-1] - interp_target

        dx = numpy.zeros((rg.num_nodes, 3))
        dm = 2*diff*self.J[:,T-1]
        for k in range(3):
            dx[:,k] = 2.*diff*self.J[:,T-1] \
                                *(-1)*d_interp[:,k]

        dJ = diff * diff
        dx *= self.g_eps * rg.element_volumes[0]
        dm *= self.g_eps * rg.element_volumes[0]
        dJ *= self.g_eps * rg.element_volumes[0]

        # test the endpoint gradient
        if testGradient:
            objOld = self.objectiveFun()
            eps = 1e-8
            x = self.xt[:,:,T-1]
            m = self.m[:,T-1]
            J = self.J[:,T-1]
            xr = numpy.random.randn(x.shape[0], x.shape[1])
            mr = numpy.random.randn(m.shape[0])
            jr = numpy.random.randn(J.shape[0])

            x1 = self.xt[:,:,T-1] + eps * xr
            m1 = self.m[:,T-1] + eps * mr
            J1 = self.J[:,T-1] + eps * jr
            interp_target = kernelMatrix_fort.applyk(x1, rg.nodes, self.dual_target, self.khs, self.kho, self.rg.num_nodes)
            diff = m1 - interp_target.real
            sqrtJ = numpy.sqrt(J1)
            objFun = numpy.dot(diff*sqrtJ, sqrtJ*diff) * self.g_eps * \
                                         rg.element_volumes[0]

            ip = numpy.multiply(dx, xr).sum(axis=1).sum() \
                        + numpy.dot(dm, mr)  \
                        + numpy.dot(dJ, jr)
            logging.info("Endpoint gradient test: %f, %f" % \
                                ((objFun - objOld)/eps, ip))

            if (self.verbose_file_output):
                rg.create_vtk_sg()
                rg.add_vtk_point_data(diff.real, "diff")
                rg.add_vtk_point_data(d_interp.real, "d_interp")
                rg.add_vtk_point_data(self.J[:,T-1], "J")
                rg.add_vtk_point_data(dJ, "dJ")
                rg.add_vtk_point_data(self.target, "target")
                rg.add_vtk_point_data(interp_target, "interp_target")
                rg.add_vtk_point_data(dm.real, "dm")
                rg.add_vtk_point_data(self.m[:,T-1], "m")
                rg.add_vtk_point_data(dx.real, "dx")
                rg.vtk_write(0, "grad_test", output_dir=self.output_dir)

        return [dx, dm, dJ]
    def __init__(self, output_dir, config_name, letter_match=None):
        self.num_points = None
        self.domain_max = None
        self.dx = None
        self.verbose_file_output = False
        self.output_dir = output_dir
        self.spline_interp = False
        # used only for letter examples
        self.letter_match = letter_match

        smoothImageConfig.configure(self, config_name)

        self.rg = regularGrid.RegularGrid(self.dim, self.num_points, \
                             self.domain_max, self.dx, "meta")
        self.times = numpy.linspace(self.time_min, self.time_max, \
                            self.num_times)
        self.dt = (self.time_max - self.time_min) / (self.num_times - 1)
        self.optimize_iteration = 0
        self.g_eps = 1.

        logging.info("sigma: %f" % self.sigma)
        logging.info("sfactor: %f" % self.sfactor)
        logging.info("num_points: %s" % str(self.rg.num_points))
        logging.info("domain_max: %s" % str(self.rg.domain_max))
        logging.info("dx: %s" % str(self.rg.dx))
        logging.info("dt: %f" % self.dt)

        rg = self.rg
        self.x0 = self.rg.nodes.copy()
        self.xt = numpy.zeros((rg.num_nodes, 3, self.num_times))
        self.v = numpy.zeros((rg.num_nodes, 3, self.num_times))
        self.m = numpy.zeros((rg.num_nodes, self.num_times))
        self.z = numpy.zeros((rg.num_nodes, 3, self.num_times))
        self.J = numpy.ones((rg.num_nodes, self.num_times))
        self.id_x = self.rg.nodes[:,0].copy()
        self.id_y = self.rg.nodes[:,1].copy()
        self.m = numpy.zeros((rg.num_nodes, self.num_times))
        self.alpha = numpy.zeros(rg.num_nodes)
        self.alpha_state = numpy.zeros_like(self.alpha)

        rg.create_vtk_sg()
        rg.add_vtk_point_data(self.template_in, "template_in")
        rg.add_vtk_point_data(self.target_in, "target_in")
        rg.vtk_write(0, "images", output_dir=self.output_dir)

        if self.spline_interp:
            si = SplineInterp(rg, self.KH, self.template_in)
            self.dual_template = si.minimize()
            si = SplineInterp(rg, self.KH, self.target_in)
            self.dual_target = si.minimize()
        else:
            self.dual_template = self.template_in.copy()
            self.dual_target = self.target_in.copy()

        (templ, dtempl) = kernelMatrix_fort.applyk_and_diff( \
                    rg.nodes, rg.nodes, self.dual_template,
                    self.khs, self.kho, self.rg.num_nodes)
        self.target = kernelMatrix_fort.applyk( \
                    rg.nodes, rg.nodes, self.dual_target,
                    self.khs, self.kho, self.rg.num_nodes)
        self.template = templ
        self.D_template = dtempl

        if True:
            temp = numpy.zeros(rg.num_nodes)
            temp[50] = 1.
            kvt = kernelMatrix_fort.applyk( \
                        rg.nodes, rg.nodes, temp,
                        self.kvs, self.kvo, self.rg.num_nodes)
            kht = kernelMatrix_fort.applyk( \
                        rg.nodes, rg.nodes, temp,
                        self.khs, self.kho, self.rg.num_nodes)
            rg.create_vtk_sg()
            rg.add_vtk_point_data(self.template, "template")
            rg.add_vtk_point_data(self.D_template, "D_template")
            rg.add_vtk_point_data(self.target, "target")
            rg.add_vtk_point_data(kvt, "kvt")
            rg.add_vtk_point_data(kht, "kht")
            rg.vtk_write(0, "initial_data", output_dir=self.output_dir)

        tmpMax = numpy.max(numpy.abs(self.template))
        tarMax = numpy.max(numpy.abs(self.target))
        self.template /= tmpMax
        self.dual_template /= tmpMax
        self.target /= tarMax
        self.dual_target /= tarMax
    def __init__(self, output_dir, config_name, letter_match=None):
        self.num_points = None
        self.domain_max = None
        self.dx = None
        self.verbose_file_output = False
        self.output_dir = output_dir
        self.spline_interp = False
        self.noJ = True
        self.unconstrained = False
        # used only for letter examples
        self.letter_match = letter_match

        smoothImageConfig.configure(self, config_name)

        self.rg = regularGrid.RegularGrid(self.dim, self.num_points, \
                             self.domain_max, self.dx, "meta")
        self.times = numpy.linspace(self.time_min, self.time_max, \
                            self.num_times)
        self.dt = (self.time_max - self.time_min) / (self.num_times - 1)
        self.optimize_iteration = 0
        self.g_eps = 1.

        self.khSmooth =0.2*numpy.asarray(self.rg.dx).max() # self.khs/2
        logging.info("sigma: %f" % self.sigma)
        logging.info("sfactor: %f" % self.sfactor)
        logging.info("num_points: %s" % str(self.rg.num_points))
        logging.info("domain_max: %s" % str(self.rg.domain_max))
        logging.info("dx: %s" % str(self.rg.dx))
        logging.info("dt: %f" % self.dt)
        logging.info('khSmooth: %f'% self.khSmooth)

        rg = self.rg
        self.x0 = self.rg.nodes.copy()
        self.xt = numpy.zeros((rg.num_nodes, 3, self.num_times))
        self.v = numpy.zeros((rg.num_nodes, 3, self.num_times))
        self.m = numpy.zeros((rg.num_nodes, self.num_times))
        self.z = numpy.zeros((rg.num_nodes, 3, self.num_times))
        self.id_x = self.rg.nodes[:,0].copy()
        self.id_y = self.rg.nodes[:,1].copy()
        self.m = numpy.zeros((rg.num_nodes, self.num_times))
        self.alpha = numpy.zeros(rg.num_nodes)
        self.alpha_state = numpy.zeros_like(self.alpha)
        if self.unconstrained:
            self.noJ = True
            self.z0 = numpy.zeros((rg.num_nodes, 3))
            self.z0weight = 100*numpy.ones((rg.num_nodes,1))
            self.z0_state = numpy.zeros((rg.num_nodes, 3))

        if not self.noJ:
            self.J = numpy.ones((rg.num_nodes, self.num_times))

        rg.create_vtk_sg()
        rg.add_vtk_point_data(self.template_in, "template_in")
        rg.add_vtk_point_data(self.target_in, "target_in")
        rg.vtk_write(0, "images", output_dir=self.output_dir)

        if self.spline_interp:
            trg = kernelMatrix_fort.applyk( \
                rg.nodes, rg.nodes, self.target_in,
                self.khs/4, self.kho, self.rg.num_nodes)
            tpl = kernelMatrix_fort.applyk( \
                rg.nodes, rg.nodes, self.template_in,
                self.khs/4, self.kho, self.rg.num_nodes)
            self.khSmooth = self.khs
            logging.info('RKHS Projection Template')
            si = SplineInterp(rg, self.khs, self.kho, tpl,True)
            self.dual_template = si.minimize()
            logging.info('RKHS Projection Target')
            si = SplineInterp(rg, self.khs, self.kho, trg)
            self.dual_target = si.minimize()
        else:
            self.dual_template = self.template_in.copy()
            self.dual_target = self.target_in.copy()

        (templ, dtempl) = kernelMatrix_fort.applyk_and_diff( \
                    rg.nodes, rg.nodes, self.dual_template,
                    self.khSmooth, self.kho, self.rg.num_nodes)
        self.target = kernelMatrix_fort.applyk( \
                    rg.nodes, rg.nodes, self.dual_target,
                    self.khSmooth, self.kho, self.rg.num_nodes)
        self.template = templ
        self.D_template = dtempl

        if True:
            temp = numpy.zeros(rg.num_nodes)
            temp[rg.num_nodes/2 + rg.num_points[1]/2] = 1.
            kvt = kernelMatrix_fort.applyk( \
                        rg.nodes, rg.nodes, temp,
                        self.kvs, self.kvo, self.rg.num_nodes)
            kht = kernelMatrix_fort.applyk( \
                        rg.nodes, rg.nodes, temp,
                        self.khs, self.kho, self.rg.num_nodes)
            rg.create_vtk_sg()
            rg.add_vtk_point_data(self.template, "template")
            rg.add_vtk_point_data(self.D_template, "D_template")
            rg.add_vtk_point_data(self.target, "target")
            rg.add_vtk_point_data(kvt, "kvt")
            rg.add_vtk_point_data(kht, "kht")
            rg.vtk_write(0, "initial_data", output_dir=self.output_dir)

        tmpMax = numpy.max(numpy.abs(self.template))
        tarMax = numpy.max(numpy.abs(self.target))
        self.D_template /= tmpMax
        self.template /= tmpMax
        self.dual_template /= tmpMax
        self.target /= tarMax
        self.dual_target /= tarMax
        self.z0weight[:] = numpy.sqrt(1e-6 + (self.D_template**2).sum(axis=1)[..., numpy.newaxis])