Esempio n. 1
0
    def test_radiation(self):
        m = 1000  # voxels
        n = 200  # beams
        dose = 1.0
        A = np.random.rand(m, n)
        labels = (np.random.rand(m) > 0.2).astype(int)

        # Dose matrix with target voxels receive ~3x radiation of non-target voxels.
        # Label 0 = tumor, label 1 = organ-at-risk.
        FACTOR = 3
        for i, label in enumerate(labels):
            if label == 0:
                A[i, :] *= FACTOR

        # Solve radiation treatment planning problem.
        x = Variable(n)
        y = Variable(m)
        y_ptv = y[labels == 0]
        y_oar = y[labels == 1]
        obj = sum(neg(y_ptv - dose) + 2 * pos(y_ptv - dose)) + sum(
            1.6 * pos(y_oar))
        constr = [
            A * x == y, x >= 0,
            quantile(y_ptv, 0.85) >= 0.95,
            quantile(y_ptv, 0.15) <= 1.0,
            quantile(y_oar, 0.5) <= 0.35
        ]
        p = Problem(Minimize(obj), constr)

        # Plot CDF for 1st and 2nd step.
        p.solve(two_step=False, slack=False)
        self.plot_cdf(y_oar.value, "b--")
        self.plot_cdf(y_ptv.value, "r--")

        p.solve(two_step=True, slack=False)
        oar, = self.plot_cdf(y_oar.value, "b-")
        ptv, = self.plot_cdf(y_ptv.value, "r-")

        # Label constraints on plot.
        plt.plot(0.95,
                 0.85,
                 marker=">",
                 markersize=self.markersize,
                 color="red")
        plt.plot(1.0,
                 0.15,
                 marker="<",
                 markersize=self.markersize,
                 color="red")
        plt.plot(0.35,
                 0.5,
                 marker="<",
                 markersize=self.markersize,
                 color="blue")
        plt.axvline(dose, color="red", linestyle=":", linewidth=1.0)
        plt.xlim(0, 1.2)
        plt.legend([oar, ptv], ["OAR", "PTV"])
Esempio n. 2
0
    def test_constraints(self):
        obj = norm(self.x)
        constr = [quantile(self.x, 0.6) <= -1]
        p = ccprob.Problem(Minimize(obj), constr)
        p.solve()
        self.assertTrue(
            np.sum(self.x.value <= -1 + self.tolerance) >= 0.6 * self.x.size)

        b = np.abs(np.random.randn(self.x.size))
        obj = norm(self.x - b)
        constr = [quantile(self.x, 0.7) >= 1]
        p = ccprob.Problem(Minimize(obj), constr)
        p.solve()
        self.assertTrue(
            np.sum(self.x.value >= 1 - self.tolerance) >= np.round(1 - 0.7) *
            self.x.size)
Esempio n. 3
0
    def test_properties(self):
        q = quantile(self.x, self.f)
        self.assertFalse(q.is_atom_convex())
        self.assertFalse(q.is_atom_concave())
        self.assertTrue(q.is_incr(0))
        self.assertFalse(q.is_decr(0))
        self.assertFalse(q.is_pwl())

        self.assertEqual(quantile(0, self.f).sign_from_args(), (True, True))
        self.assertEqual(quantile(1, self.f).sign_from_args(), (True, False))
        self.assertEqual(quantile(-1, self.f).sign_from_args(), (False, True))

        self.x.value = np.random.randn(10)
        self.assertEqual(q.sign_from_args(), (False, False))
        self.assertItemsAlmostEqual(q.value,
                                    np.percentile(self.x.value, 100 * self.f))
Esempio n. 4
0
    def test_reduction_nested(self):
        # Minimize 2*quantile(y, 0.5)) + 1
        #   subject to y >= 0.
        t = Variable()
        obj = 2 * t + 1
        constr = [quantile(self.y, 0.5) <= t, self.y >= 0]
        p0 = ccprob.Problem(Minimize(obj), constr)
        p0.solve()
        y_epi = self.y.value

        obj = 2 * quantile(self.y, 0.5) + 1
        constr = [self.y >= 0]
        p1 = ccprob.Problem(Minimize(obj), constr)
        p1.solve()
        self.assertAlmostEqual(p1.value, p0.value)
        self.assertItemsAlmostEqual(self.y.value, y_epi)

        # Minimize -2*quantile(y, 0.75) + 3
        #   subject to y <= 5.
        obj = -2 * t + 3
        constr = [quantile(self.y, 0.75) >= t, self.y <= 5]
        p0 = ccprob.Problem(Minimize(obj), constr)
        p0.solve()
        y_epi = self.y.value

        obj = -2 * quantile(self.y, 0.75) + 3
        constr = [self.y <= 5]
        p1 = ccprob.Problem(Minimize(obj), constr)
        p1.solve()
        self.assertAlmostEqual(p1.value, p0.value)
        self.assertItemsAlmostEqual(self.y.value, y_epi)

        # Minimize quantile(y, 0.75) - quantile(y, 0.5)
        u = Variable()
        obj = t - u
        constr = [
            quantile(self.y, 0.75) <= t,
            quantile(self.y, 0.5) >= u, self.y >= 0, self.y <= 1
        ]
        p0 = ccprob.Problem(Minimize(obj), constr)
        p0.solve()
        y_epi = self.y.value

        obj = quantile(self.y, 0.75) - quantile(self.y, 0.5)
        constr = [self.y >= 0, self.y <= 1]
        p1 = ccprob.Problem(Minimize(obj), constr)
        p1.solve()
        self.assertAlmostEqual(p1.value, p0.value)
        self.assertItemsAlmostEqual(self.y.value, y_epi)
Esempio n. 5
0
    def test_reduction_basic(self):
        # Minimize quantile(y, 0.5) subject to y >= 0.
        t = Variable()
        constr = [quantile(self.y, 0.5) <= t, self.y >= 0]
        p0 = ccprob.Problem(Minimize(t), constr)
        p0.solve()
        y_epi = self.y.value

        obj = quantile(self.y, 0.5)
        constr = [self.y >= 0]
        p1 = ccprob.Problem(Minimize(obj), constr)
        p1.solve()
        self.assertAlmostEqual(p1.value, p0.value)
        self.assertItemsAlmostEqual(self.y.value, y_epi)

        # Maximize quantile(y, 0.75) subject to y <= 5.
        constr = [quantile(self.y, 0.75) >= t, self.y <= 5]
        p0 = ccprob.Problem(Maximize(t), constr)
        p0.solve()
        y_epi = self.y.value

        obj = quantile(self.y, 0.75)
        constr = [self.y <= 5]
        p1 = ccprob.Problem(Maximize(obj), constr)
        p1.solve()
        self.assertAlmostEqual(p1.value, p0.value)
        self.assertItemsAlmostEqual(self.y.value, y_epi)

        # Minimize quantile(abs(A*x - b), 0.5)
        #   subject to 0 <= x <= 1,
        #              quantile(x, 0.25) >= 0.1
        b = np.random.randn(self.A.shape[0])
        constr = [
            quantile(abs(self.A * self.x - b), 0.5) <= t, self.x >= 0,
            self.x <= 1,
            quantile(self.x, 0.25) >= 0.1
        ]
        p0 = ccprob.Problem(Minimize(t), constr)
        p0.solve()
        x_epi = self.x.value

        obj = quantile(abs(self.A * self.x - b), 0.5)
        constr = [self.x >= 0, self.x <= 1, quantile(self.x, 0.25) >= 0.1]
        p1 = ccprob.Problem(Minimize(obj), constr)
        p1.solve()
        self.assertAlmostEqual(p1.value, p0.value)
        self.assertItemsAlmostEqual(self.x.value, x_epi)
Esempio n. 6
0
    def test_radiation_slack(self):
        m = 1000  # voxels
        n = 200  # beams
        dose = 1.0
        A = np.random.rand(m, n)
        labels = (np.random.rand(m) > 0.2).astype(int)

        # Dose matrix with target voxels receive ~3x radiation of non-target voxels.
        # Label 0 = tumor, label 1 = organ-at-risk.
        FACTOR = 3
        for i, label in enumerate(labels):
            if label == 0:
                A[i, :] *= FACTOR

        # Solve radiation treatment planning problem.
        x = Variable(n)
        y = Variable(m)
        y_ptv = y[labels == 0]
        y_oar = y[labels == 1]
        obj = sum(2.5 * neg(y_ptv - dose) + 5 * pos(y_ptv - dose)) + sum(
            1.6 * pos(y_oar))
        constr = [
            A * x == y, x >= 0,
            quantile(y_ptv, 0.85) >= 0.95,
            quantile(y_ptv, 0.15) <= 1.0
        ]
        p = Problem(Minimize(obj), constr)
        p.solve(two_step=True, slack=False)

        # Plot CDF of 2-step solution.
        # self.plot_cdf(y_oar.value, "b-")
        # self.plot_cdf(y_ptv.value, "r-")
        plt.plot(0.95,
                 0.85,
                 marker=">",
                 markersize=self.markersize,
                 color="red")
        plt.plot(1.0,
                 0.15,
                 marker="<",
                 markersize=self.markersize,
                 color="red")
        # plt.show()

        # First pass infeasible with additional constraint.
        constr += [quantile(y_oar, 0.3) <= 0.15]
        p = Problem(Minimize(obj), constr)
        with self.assertRaises(SolverError) as cm:
            p.solve(slack=False)

        # Plot CDF of slack solution with constraint.
        p.solve(two_step=False, slack=True)
        self.plot_cdf(y_oar.value, "b--")
        self.plot_cdf(y_ptv.value, "r--")
        qt = quantile(y_oar, 0.3).value
        print("OAR quantile with slack:", qt)

        p.solve(two_step=True, slack=True)
        oar, = self.plot_cdf(y_oar.value, "b-")
        ptv, = self.plot_cdf(y_ptv.value, "r-")

        # Label original and slack bound.
        plt.plot([0.15, qt], [0.3, 0.3], "b-")
        plt.plot(qt,
                 0.3,
                 marker="<",
                 markersize=self.markersize,
                 color="blue",
                 markerfacecolor="white",
                 markeredgecolor="blue")
        plt.plot(0.15,
                 0.3,
                 marker="<",
                 markersize=self.markersize,
                 color="blue")
        plt.axvline(dose, color="red", linestyle=":", linewidth=1.0)
        plt.xlim(0, 1.2)
        plt.legend([oar, ptv], ["OAR", "PTV"])