namespace Dakota {

/** \page VarContainersViews Working with Variable Containers and Views

\htmlonly
<b>Working with Variable Containers and Views Table of Contents</b>
<ul>
<li> <a href="VarContainersViews.html#VarStorage">Storage in Variables</a> 
<li> <a href="VarContainersViews.html#SharedVarStorage">Storage in SharedVariablesData</a>
<li> <a href="VarContainersViews.html#VarActiveInactive">Active and inactive views</a> 

</ul>
\endhtmlonly


Variable views control the subset of variable types that are active
and inactive within a particular iterative study.  For design
optimization and uncertainty quantification (UQ), for example, the
active variables view consists of design or uncertain types,
respectively, and any other variable types are carried along invisible
to the iterative algorithm being employed.  For parameter studies and
design of experiments, however, a variable subset view is not imposed
and all variables are active.  Selected UQ methods can also be toggled
into an "All" view using the \c active \c all variables input specification.
When not in an All view, finer gradations within the uncertain
variable sets are also relevant: probabilistic methods (reliability,
stochastic expansion) view aleatory uncertain variables as active,
nonprobabilistic methods (interval, evidence) view epistemic uncertain
variables as active, and a few UQ methods (sampling) view both as
active.  In a more advanced NestedModel use case such as optimization
under uncertainty, design variables are active in the outer
optimization context and the uncertain variables are active in the
inner UQ context, with an additional requirement on the inner UQ level
to return derivatives with respect to its "inactive" variables (i.e.,
the design variables) for use in the outer optimization loop.

For efficiency, contiguous arrays of data store variable information
for each of the domain types (continuous, discrete integer, and
discrete real), but active and inactive views into them permit
selecting subsets in a given context.  This management is encapsulated
into the Variables and SharedVariablesData classes.  This page
clarifies concepts of relaxed (formerly merged) vs. mixed,
fine-grained vs. aggregated types, domain types, and views into
contiguous arrays.

We begin with an overview of the storage and management concept, for
which the following two sections describe the storage of variable
values and meta-data about their organization, used in part to manage
views.  They are intended to communicate rationale to maintainers of
Variables and SharedVariablesData classes.  The final section provides
a discussion of active and inactive views.


\section VarStorage Storage in Variables

As described in the \ref DevVariables "Main Page Variables", a
Variables object manages variable types (design, aleatory uncertain,
epistemic uncertain, and state) and domain types (continuous, discrete
integer, and discrete real) and supports different approaches to
either distinguishing among these types or aggregating them.  Two
techniques are used in cooperation to accomplish this management: (1)
class specialization (RelaxedVariables or MixedVariables) and (2) views
into contiguous variable arrays.  The latter technique is used
whenever it can satisfy the requirement, with fallback to class
specialization when it cannot.  In particular, aggregation or
separation of variable types can be accomplished with views, but for
aggregation or separation of variable domains, we must resort to class
specialization in order to relax discrete domain types.  In this class
specialization, a RelaxedVariables object combines continuous and
discrete types (relaxing integers to reals) whereas a MixedVariables
object maintains the integer/real distinction throughout.  

The core data for a Variables instance is stored in a set of three
continguous arrays, corresponding to the domain types: \ref
Dakota::Variables::allContinuousVars "allContinuousVars", \ref
Dakota::Variables::allDiscreteIntVars "allDiscreteIntVars", and \ref
Dakota::Variables::allDiscreteRealVars "allDiscreteRealVars", unique
to each Variables instance.

Within the core variable data arrays, data corresponding to different
aggregated variable types are stored in sequence for each domain type:
<ul>
  <li> continuous: [design, aleatory uncertain, epistemic uncertain, state]</li>
  <li> discrete integer: [design, aleatory uncertain, (epistemic uncertain), state]</li>
  <li> discrete real: [design, aleatory uncertain, (epistemic uncertain), state]</li>
</ul>
Note there are currently no epistemic discrete variables.  This domain
type ordering (continuous, discrete integer, discrete real) and
aggregated variable type ordering (design, aleatory uncertain,
epistemic uncertain, state) is preserved whenever distinct types are
flattened into single contiguous arrays.  Note that the aleatory and
epistemic uncertain variables contain sub-types for different
distributions (e.g., normal, uniform, histogram, poisson), and
discrete integer types include both integer ranges and integer set
sub-types.  All sub-types are ordered according to their order of 
appearance in dakota.input.nspec.

When relaxing in MixedVariables, the \ref
Dakota::Variables::allContinuousVars "allContinuousVars" will also
aggregate the discrete types, such that they contain ALL design, then
ALL uncertain, then ALL state variables, each in aggregated type
order; the \ref Dakota::Variables::allDiscreteIntVars "allDiscreteIntVars" 
and \ref Dakota::Variables::allDiscreteRealVars "allDiscreteRealVars" 
arrays are empty.


\section SharedVarStorage Storage in SharedVariablesData

Each Variables instance contains a reference-counted
SharedVariablesData object that stores information on the variables
configuration.  This configuration data includes counts, types, IDs,
and labels, which are often the same across many Variables instances.
Thus, SharedVariablesData is intended to reduce the memory footprint
by allowing the sharing of a single copy of redundant information
among different Variables instances.  

One of the purposes of this shared information is to support mappings
between variable types, IDs, and indices into the storage arrays.
Variable "types" refer to the fine-grained variable types a user would
specify in an input file, as enumerated in DataVariables.hpp, e.g,
CONTINUOUS_DESIGN, WEIBULL_UNCERTAIN, DISCRETE_STATE_RANGE, etc.  \ref
Dakota::SharedVariablesDataRep::variablesComponents
"variablesComponents" is a map from these variable types to counts of
how many are present.

In contrast, the 
\ref Dakota::SharedVariablesDataRep::variablesCompsTotals "variablesCompsTotals" 
array stores total counts of each "aggregated type" (design, aleatory
uncertain, epistemic uncertain, state) which might be selected to be
active in a given view.  Thus this array has length 12 to track the
combinations of three domain type storage arrays with four possible
aggregated variable types: {continuous, discrete integer, discrete
real} x {design, aleatory uncertain, epistemic uncertain, state}.  For
example, the first entry of this array stores the number of continuous
design variables, the second the number of discrete integer design
(including both discrete design range and discrete design set integer
types), and the last the number of discrete real state variables.

The arrays 
\ref Dakota::SharedVariablesDataRep::allContinuousTypes "allContinuousTypes", 
\ref Dakota::SharedVariablesDataRep::allDiscreteIntTypes "allDiscreteIntTypes", and
\ref Dakota::SharedVariablesDataRep::allDiscreteRealTypes "allDiscreteRealTypes"
are sized to match the corresponding core domain type storage arrays.
They track the fine-grained variable type stored in that entry of the
data array (since when relaxed, the continuous array may be storing
data corresponding to discrete data).

Finally 
\ref Dakota::SharedVariablesDataRep::allContinuousIds "allContinuousIds"
stores the 1-based IDs of the variables stored in the
allContinuousVars array, i.e., the variable number of all the problem
variables considered as a single contiguous set, in aggregate type
order.  For relaxed (formerly merged) views,
\ref Dakota::SharedVariablesDataRep::relaxedDiscreteIds "relaxedDiscreteIds"
stores the 1-based IDs of the variables which have been relaxed into
the continuous array.

These counts, types, and IDs are most commonly used within the Model
classes for mappings between variables objects at different levels of
a model recursion.  See, for example, the variable mappings in the
NestedModel constructor.


\section VarActiveInactive Active and inactive views

The pair 
\ref Dakota::SharedVariablesDataRep::variablesView "SharedVariablesDataRep::variablesView"
tracks the active and inactive views of the data, with values taken
from the enum in DataVariables.hpp.  The valid values include EMPTY and
the combinations {relaxed, mixed} x {all, design, aleatory uncertain,
epistemic uncertain, uncertain, state}.  The ALL cases indicate
aggregation of the design, aleatory uncertain, epistemic uncertain,
and state types, whereas the DISTINCT cases indicate either no
aggregation (design, aleatory uncertain, epistemic uncertain, state)
or reduced aggregation (aleatory+epistemic uncertain).  The active
view is determined by the algorithm in use, managed in \ref
Variables::get_view "Variables::get_view()".  Any inactive view is set
based on higher level iteration within a model recursion (e.g., a
NestedModel), which enables lower level iteration to return
derivatives with respect to variables that are active at the higher
level.  In the case where there is no higher level iteration, then the
inactive view will remain EMPTY.  It is important to stress that
"inactive" at one level corresponds to active at another, and
therefore the inactive set of variables should not be interpreted as
the strict complement of the active set of variables; rather, active
and inactive are both subsets whose union may still be a subset of the
total container (more precise terminology might involve "primary"
active and "secondary" active or similar).  An active complement view
could potentially be supported in the future, should the need arise,
although this view would require management of non-contiguous portions
of the aggregated arrays.

Given these groupings (views), the active and inactive subsets of the
\ref Dakota::Variables::allContinuousVars "allContinuousVars", 
\ref Dakota::Variables::allDiscreteIntVars "allDiscreteIntVars",
and \ref Dakota::Variables::allDiscreteRealVars "allDiscreteRealVars" 
arrays are always contiguous, permitting vector views of the
underlying data using either Teuchos::View (for numerical vectors) or
Boost.MultiArray (for book-keeping arrays) views. 

When a Variables envelope is constructed, its letter is initialized to
either a RelaxedVariables or MixedVariables object depending on the
active view.  The derived classes size the contiguous storage arrays
to accomodate all the problem variables, and then initialize active
views into them, which could involve either subsets (DISTINCT active
views) or views of the full arrays (ALL active views).  Inactive
views, on the other hand, are initialized during construction of a
model recursion (e.g., a call to Model::inactive_view() in the
NestedModel constructor).  Thus, active variable subsets are always
available but inactive variable subsets will be EMPTY prior to them
being initialized within a Model recursion.  

Accessors for continuous variables include:
<ul>
  <li> continuous_variables(): returns the active view which might return all (ALL views) or a subset (DISTINCT views) such as design, uncertain, only aleatory uncertain, etc.</li>
  <li> inactive_continuous_variables(): returns the inactive view which which is either a subset or empty</li>
  <li> all_continuous_variables(): returns the full vector \ref Dakota::Variables::allContinuousVars "allContinuousVars"</li>
</ul>
and this pattern is followed for active/inactive/all access to
discrete_int_variables() and discrete_real_variables() as well as for
labels, IDs, and types in SharedVariablesData and variable bounds in
Constraints.

*/

} // namespace Dakota
