Optimization Functions

matRad implements objectives and constraints for the optimization of dose distributions, as well as objectives acting directly on the fluence. All of them derive from matRad_OptimizationFunction, which provides what is independent of the optimized quantity: the parameter description used by the GUI, struct serialization and instantiation from a struct.

From it derive the quantity specific bases: matRad_DoseOptimizationFunction for functions of the dose, differentiating between dose objectives and constraints, and matRad_FluenceOptimizationFunction for fluence objectives.

Dose Objectives

class DoseObjectives.matRad_EUD(penalty, eudRef, eudExponent)

Bases: DoseObjectives.matRad_DoseObjective

matRad_EUD Implements a penalized equivalent uniform dose objective

See matRad_DoseObjective for interface description

References

Copyright 2020-2026 the matRad development team.

This file is part of the matRad project. It is subject to the license terms in the LICENSE file found in the top-level directory of this distribution and at https://github.com/e0404/matRad/LICENSE.md. No part of the matRad project, including this file, may be copied, modified, propagated, or distributed except according to the terms contained in the LICENSE file.


If we have a struct in first argument

Property Summary
name = 'EUD'
parameterNames = {'EUD^{ref}','k'}
parameterTypes = {'dose','numeric'}
parameters = {0,3.5}
penalty = 1
Method Summary
computeDoseObjectiveFunction(dose)

get exponent for EUD

computeDoseObjectiveGradient(dose)

get exponent for EUD

class DoseObjectives.matRad_DoseObjective(varargin)

Bases: matRad_DoseOptimizationFunction

matRad_DoseObjective: Interface for optimization objectives

This abstract base class provides the structure of optimization objectives like mean dose, squared deviation, EUD, dose-volume etc. Implementations can be found in the DoseObjectives package


default initialization from struct (parameters & penalty)

Property Summary
penalty

Optimization penalty

Method Summary
static availableRobustness()
computeDoseObjectiveFunction(dose)
computeDoseObjectiveGradient(dose)
struct()
class DoseObjectives.matRad_SquaredUnderdosing(penalty, dMin)

Bases: DoseObjectives.matRad_DoseObjective

matRad_SquaredUnderdosing Implements a penalized squared underdosing objective

See matRad_DoseObjective for interface description

References

Copyright 2020-2026 the matRad development team.

This file is part of the matRad project. It is subject to the license terms in the LICENSE file found in the top-level directory of this distribution and at https://github.com/e0404/matRad/LICENSE.md. No part of the matRad project, including this file, may be copied, modified, propagated, or distributed except according to the terms contained in the LICENSE file.


If we have a struct in first argument

Property Summary
name = 'Squared Underdosing'
parameterNames = {'d^{min}'}
parameterTypes = {'dose'}
parameters = {60}
penalty = 1
Method Summary
computeDoseObjectiveFunction(dose)

overdose : dose minus prefered dose

computeDoseObjectiveGradient(dose)

overdose : dose minus prefered dose

class DoseObjectives.matRad_SquaredDeviation(penalty, dRef)

Bases: DoseObjectives.matRad_DoseObjective

matRad_SquaredDeviation Implements a penalized least squares objective

See matRad_DoseObjective for interface description

References

Copyright 2015-2026 the matRad development team.

This file is part of the matRad project. It is subject to the license terms in the LICENSE file found in the top-level directory of this distribution and at https://github.com/e0404/matRad/LICENSE.md. No part of the matRad project, including this file, may be copied, modified, propagated, or distributed except according to the terms contained in the LICENSE file.


If we have a struct in first argument

Property Summary
name = 'Squared Deviation'
parameterNames = {'d^{ref}'}
parameterTypes = {'dose'}
parameters = {60}
penalty = 1
Method Summary
computeDoseObjectiveFunction(dose)

deviation : dose minus prefered dose

computeDoseObjectiveGradient(dose)

deviation : Dose minus prefered dose

static availableRobustness()
class DoseObjectives.matRad_MaxDVH(penalty, dRef, vMaxPercent)

Bases: DoseObjectives.matRad_DoseObjective

matRad_MaxDVH Implements a penalized maximum DVH objective

See matRad_DoseObjective for interface description

References

Copyright 2020-2026 the matRad development team.

This file is part of the matRad project. It is subject to the license terms in the LICENSE file found in the top-level directory of this distribution and at https://github.com/e0404/matRad/LICENSE.md. No part of the matRad project, including this file, may be copied, modified, propagated, or distributed except according to the terms contained in the LICENSE file.


If we have a struct in first argument

Property Summary
name = 'Max DVH'
parameterNames = {'d','V^{max}'}
parameterTypes = {'dose','numeric'}
parameters = {30,95}
penalty = 1
Method Summary
computeDoseObjectiveFunction(dose)

get reference Volume

computeDoseObjectiveGradient(dose)

get reference Volume

class DoseObjectives.matRad_MinDVH(penalty, dRef, vMinPercent)

Bases: DoseObjectives.matRad_DoseObjective

matRad_MinDVH Implements a penalized MinDVH objective

See matRad_DoseObjective for interface description

References

Copyright 2020-2026 the matRad development team.

This file is part of the matRad project. It is subject to the license terms in the LICENSE file found in the top-level directory of this distribution and at https://github.com/e0404/matRad/LICENSE.md. No part of the matRad project, including this file, may be copied, modified, propagated, or distributed except according to the terms contained in the LICENSE file.


if we have a struct in first argument

Property Summary
name = 'Min DVH'
parameterNames = {'d','V^{min}'}
parameterTypes = {'dose','numeric'}
parameters = {60,95}
penalty = 1
Method Summary
computeDoseObjectiveFunction(dose)

get reference Volume

computeDoseObjectiveGradient(dose)

get reference Volume

class DoseObjectives.matRad_MeanDose(penalty, dMeanRef, fDiff)

Bases: DoseObjectives.matRad_DoseObjective

matRad_MeanDose Implements a penalized MeanDose objective

See matRad_DoseObjective for interface description

References

Copyright 2020-2026 the matRad development team.

This file is part of the matRad project. It is subject to the license terms in the LICENSE file found in the top-level directory of this distribution and at https://github.com/e0404/matRad/LICENSE.md. No part of the matRad project, including this file, may be copied, modified, propagated, or distributed except according to the terms contained in the LICENSE file.


if we have a struct in first argument

Property Summary
name = 'Mean Dose'
parameterNames = {'d^{ref}','f_{diff}'}

When optimizing to a reference, one might consider using a quadratic relationship with a non-linear optimizer

parameterTypes = {'dose',{'Linear','Quadratic'}}
parameters = {0,1}
penalty = 1
Method Summary
computeDoseObjectiveFunction(dose)
computeDoseObjectiveGradient(dose)
class DoseObjectives.matRad_SquaredOverdosing(penalty, dMax)

Bases: DoseObjectives.matRad_DoseObjective

matRad_SquaredOverdosing Implements a penalized squared overdosing objective

See matRad_DoseObjective for interface description

References

Copyright 2020-2026 the matRad development team.

This file is part of the matRad project. It is subject to the license terms in the LICENSE file found in the top-level directory of this distribution and at https://github.com/e0404/matRad/LICENSE.md. No part of the matRad project, including this file, may be copied, modified, propagated, or distributed except according to the terms contained in the LICENSE file.


If we have a struct in first argument

Property Summary
name = 'Squared Overdosing'
parameterNames = {'d^{max}'}
parameterTypes = {'dose'}
parameters = {30}
penalty = 1
Method Summary
computeDoseObjectiveFunction(dose)

overdose : dose minus prefered dose

computeDoseObjectiveGradient(dose)

overdose : dose minus prefered dose

Dose Constraints

class DoseConstraints.matRad_MinMaxDose(minDose, maxDose, method)

Bases: DoseConstraints.matRad_DoseConstraint

matRad_MinMaxDose Implements a MinMaxDose constraint

See matRad_DoseConstraint for interface description

use log sum exp approximation, see appendix A in http://scitation.aip.org/content/aapm/journal/medphys/41/8/10.1118/1.4883837


Copyright 2020-2026 the matRad development team.

This file is part of the matRad project. It is subject to the license terms in the LICENSE file found in the top-level directory of this distribution and at https://github.com/e0404/matRad/LICENSE.md. No part of the matRad project, including this file, may be copied, modified, propagated, or distributed except according to the terms contained in the LICENSE file.


If we have a struct in first argument

Property Summary
name = 'Min/Max dose constraint'
parameterNames = {'d^{min}','d^{max}','method'}
parameterTypes = {'dose','dose',{'approx','voxelwise'}}
parameters = {0,30,1}
epsilon = 1e-3

slack parameter for the logistic approximation

Method Summary
struct(this)
upperBounds(this, n)
lowerBounds(this, n)
getDoseConstraintJacobianStructure(this, n)
computeDoseConstraintFunction(this, dose)

cDose(2) = dose_max + this.epsilon * log( sum(exp((dose - dose_max)/this.epsilon))); cDose(1) = dose_min - this.epsilon * log( sum(exp((dose_min - dose)/this.epsilon)));

computeDoseConstraintJacobian(this, dose)
computeDoseConstraintFunctionLogSumExp(this, dose)
computeDoseConstraintJacobianLogSumExp(this, dose)

Validate parameters

computeDoseConstraintFunctionVoxelwise(this, dose)
computeDoseConstraintJacobianVoxelwise(this, dose)
class DoseConstraints.matRad_MinMaxEUD(exponent, eudMin, eudMax)

Bases: DoseConstraints.matRad_DoseConstraint

matRad_MinMaxEUD Implements a MinMaxEUD constraint

See matRad_DoseConstraint for interface description

References

Copyright 2020-2026 the matRad development team.

This file is part of the matRad project. It is subject to the license terms in the LICENSE file found in the top-level directory of this distribution and at https://github.com/e0404/matRad/LICENSE.md. No part of the matRad project, including this file, may be copied, modified, propagated, or distributed except according to the terms contained in the LICENSE file.


If we have a struct in first argument

Property Summary
name = 'EUD constraint'
parameterNames = {'k','EUD^{min}','EUD^{max}'}
parameterTypes = {'numeric','dose','dose'}

parameterIsDose = logical([0 1 1]);

parameters = {5,0,30}
Method Summary
struct(this)
upperBounds(this, n)
lowerBounds(this, n)
computeDoseConstraintFunction(this, dose)
computeDoseConstraintJacobian(this, dose)
class DoseConstraints.matRad_MinMaxMeanDose(minMeanDose, maxMeanDose)

Bases: DoseConstraints.matRad_DoseConstraint

matRad_MinMaxMeanDose Implements a MinMaxMeanDose constraint

See matRad_DoseConstraint for interface description

References

Copyright 2020-2026 the matRad development team.

This file is part of the matRad project. It is subject to the license terms in the LICENSE file found in the top-level directory of this distribution and at https://github.com/e0404/matRad/LICENSE.md. No part of the matRad project, including this file, may be copied, modified, propagated, or distributed except according to the terms contained in the LICENSE file.


If we have a struct in first argument

Property Summary
name = 'mean dose constraint'
parameterNames = {'\mu_d^{min}','\mu_d^{max}'}
parameterTypes = {'dose','dose'}

parameterIsDose = logical([1 1]);

parameters = {0,30}
Method Summary
upperBounds(this, n)
lowerBounds(this, n)
struct(this)
computeDoseConstraintFunction(this, dose)
computeDoseConstraintJacobian(this, dose)
DoseConstraints.matRad_MinMaxDVH
matRad_MinMaxDVH Implements a MinMaxDVH constraint

See matRad_DoseConstraint for interface description

The constraint enforces a DVH point V(d^{ref}) - the volume fraction of the structure receiving at least the reference dose d^{ref} - to lie between V^{min} and V^{max}.

The constraint value is the exact DVH point (a Heaviside/step count). Its exact derivative is a Dirac delta (zero everywhere except at the threshold) and is therefore useless for gradient-based optimization. For the Jacobian we hence approximate the Heaviside step by a logistic (sigmoid) function whose steepness is re-derived in every iteration - the dose distribution within a structure changes during optimization, so the steepness is adapted such that a “meaningful” gradient is provided for the voxels close to the threshold (those that can realistically be pushed across the DVH point). The steepness is controlled by two parameters:

voxelScalingRatio - WIDTH of the sensitivity band around the

threshold, expressed via a voxel count. The band half-width deltaDoseMax is the dose distance enclosing the closest voxelScalingRatio*N/2 voxels (default 1 -> median distance, i.e. the closest half of all voxels). Smaller values narrow the band (sharper sigmoid, fewer contributing voxels) and can be useful for OARs, where only few voxels violate the constraint.

referenceScalingVal - HOW step-like the sigmoid is at the edge of that

band: at +/- deltaDoseMax the sigmoid must be within referenceScalingVal of its asymptote (default 0.01 -> saturated to within 1%). Smaller values make the transition crisper. Largely empirical; it can make sense to reduce it as the optimization settles close to a constraint value.

See the Fluence Optimization section of the documentation for details.

References

Copyright 2020-2026 the matRad development team.

This file is part of the matRad project. It is subject to the license terms in the LICENSE file found in the top-level directory of this distribution and at https://github.com/e0404/matRad/LICENSE.md. No part of the matRad project, including this file, may be copied, modified, propagated, or distributed except according to the terms contained in the LICENSE file.


class DoseConstraints.matRad_DoseConstraint(varargin)

Bases: matRad_DoseOptimizationFunction

matRad_DoseConstraint: Interface for optimization constraints.

This abstract base class provides the interface of constraints for non-linear optimization.


default initialization from struct (parameters & penalty)

Method Summary
computeDoseConstraintFunction(this, dose)
computeDoseConstraintJacobian(this, dose)
upperBounds(this, n)
lowerBounds(this, n)
static availableRobustness()
getDoseConstraintJacobianStructure(this, n)

return the structure of the (dose-dependent) constraint function jacobian for a given length n of the dose vector. Returns a default of a jStruct

struct(this)
class DoseConstraints.matRad_DoseConstraintFromObjective(objective, maxObj, slackParameter)

Bases: DoseConstraints.matRad_DoseConstraint

matRad_ObjectiveConstraint implements a wrapper function that turns dose objectives into constraints

use log sum exp approximation, see appendix A in http://scitation.aip.org/content/aapm/journal/medphys/41/8/10.1118/1.4883837


Copyright 2020-2026 the matRad development team.

This file is part of the matRad project. It is subject to the license terms in the LICENSE file found in the top-level directory of this distribution and at https://github.com/e0404/matRad/LICENSE.md. No part of the matRad project, including this file, may be copied, modified, propagated, or distributed except according to the terms contained in the LICENSE file.


check if objective is a struct and a DoseObjective or Constraint (for init from constraint)

Property Summary
name = 'Objective Constraint'
parameterTypes = {'objFunc','scalar'}
parameterNames = {'f^{max}','slackParameter'}
objective
parameters = {1e-5,1e-3}
Method Summary
struct(this)
upperBounds(this, n)
lowerBounds(this, n)
computeDoseConstraintFunction(this, dose)
computeDoseConstraintJacobian(this, dose)
getDoseParameters(this)

get only the dose related parameters.

setDoseParameters(this, doseParams)

set only the dose related parameters.

Fluence Objectives

Fluence objectives act on the bixel weight vector directly instead of on a dose related quantity, so that they take no part in the backprojection. They are given either in pln.propOpt.fluenceObjectives or alongside the dose objectives in the cst cell, in which case the structure they are attached to is ignored - the objective still acts on the whole fluence. Since they only need the bixel to beam mapping from the dose influence matrix, they work for photons and particles alike.

class FluenceObjectives.matRad_FluenceObjective(varargin)

Bases: matRad_FluenceOptimizationFunction

matRad_FluenceObjective: Interface for optimization objectives acting on

the fluence This abstract base class provides the structure of objectives that are a function of the bixel weight vector w itself, not of the dose. They take no part in the dose backprojection / chain rule - the gradient they return is already a gradient w.r.t. the weights and is added to the weight gradient directly. Implementations can be found in the FluenceObjectives package.


Copyright 2026 the matRad development team.

This file is part of the matRad project. It is subject to the license terms in the LICENSE file found in the top-level directory of this distribution and at https://github.com/e0404/matRad/LICENSE.md. No part of the matRad project, including this file, may be copied, modified, propagated, or distributed except according to the terms contained in the LICENSE file.


default initialization from struct (parameters & penalty)

Property Summary
penalty

Optimization penalty, applied by the objective wrapper

Method Summary
struct()
computeFluenceObjectiveFunction(w)

#ok<INUSD>

computeFluenceObjectiveGradient(w)

#ok<INUSD>

class FluenceObjectives.matRad_FluenceVariance(penalty, normalization)

Bases: FluenceObjectives.matRad_FluenceObjective

matRad_FluenceVariance: penalizes the fluence variance within each beam

Beam-wise modulation reduction. With m_b the mean weight of beam b and N the number of bixels the objective acts on,

f(w) = 1/N * sum_b sum_{i in b} (w_i - m_b)^2 / normalization

which is the quadratic form w’Sw with S block diagonal and S_bb = (I - 11’/n_b)/N - see the static getQuadraticForm. A flat fluence per beam is free, any modulation costs.

Bixels of different beams are never coupled, and no assumption is made about where a bixel sits inside its beam: the objective only needs the bixel-to-beam mapping the dij carries, so it works for photons and particles alike. Smoothing that couples neighbouring bixels needs the beamlet geometry from the stf and is not available here - see matRad_FluenceOptimizationFunction.

Parameters:
normalization ‘relative’ (default) each beam’s variance is divided

by that beam’s OWN mean square and the beams are averaged, i.e. the mean squared coefficient of variation. Dimensionless, invariant under a rescaling of the fluence, so penalties transfer between plans. ‘absolute’ the plain quadratic form; its value scales with the square of the fluence magnitude

The per-beam denominator matters: normalizing by a mean square pooled over all beams would put the differences between the beam levels into the denominator, since:

sum_i w_i^2 = sum_b sum_{i in b} (w_i - m_b)^2 + sum_b n_b m_b^2

so the objective could be lowered by driving the beams apart in intensity instead of by smoothing. On an arc that concentrates the plan on a few control points, which is the opposite of what this objective is for.

References

Quadratic fluence regularization of this type is standard in fluence map optimization, e.g. https://doi.org/10.1088/0031-9155/50/8/010


Copyright 2026 the matRad development team.

This file is part of the matRad project. It is subject to the license terms in the LICENSE file found in the top-level directory of this distribution and at https://github.com/e0404/matRad/LICENSE.md. No part of the matRad project, including this file, may be copied, modified, propagated, or distributed except according to the terms contained in the LICENSE file.


Construct the objective. The beam partition is filled in later from the dij, see setupForDij.

Property Summary
name = 'Fluence Variance'
parameterNames = {'normalization'}
parameterTypes = {{'relative','absolute'}}
parameters = {1}
penalty = 1
beams = []

dij beam indices to act on; empty selects the default (FMO) beams

beamBixelIx = {}

bixel indices per selected beam, filled by setupForDij

Method Summary
getNormalization()
setupForDij(dij)

Partition the bixels by beam. Called during the initialization of the optimization problem.

computeFluenceObjectiveFunction(w)
computeFluenceObjectiveGradient(w)

the gradient is always returned as a column, matching the weight gradient of the optimization problem

struct()
matchOption(value, options, what)

#ok<INUSL>

static getQuadraticForm(dij, beams)

Explicit quadratic form S with f = w’Sw for the ‘absolute’ normalization, without needing an objective instance. The ‘relative’ normalization divides each beam block by that beam’s own mean square and is therefore not a single quadratic form.

The objective itself never builds this - it evaluates the same expression in O(numOfBixels). S is provided for inspection and for reuse elsewhere, and is dense within each beam block, so it is only practical for moderate beam sizes.

call

S = FluenceObjectives.matRad_FluenceVariance.getQuadraticForm(dij) S = FluenceObjectives.matRad_FluenceVariance.getQuadraticForm(dij,beams)