# ConditionalDimension

``ConditionalDimension(self, *args, **kwargs)``

Symbol defining a non-convex iteration sub-space derived from a `parent` Dimension, implemented by the compiler generating conditional “if-then” code within the parent Dimension’s iteration space.

## Parameters

Name Type Description Default
name str Name of the dimension. required
parent Dimension The parent Dimension. required
factor int The number of iterations between two executions of the if-branch. If None (default), `condition` must be provided. `None`
condition expr - like An arbitrary SymPy expression, typically involving the `parent` Dimension. When it evaluates to True, the if-branch is executed. If None (default), `factor` must be provided. `None`
indirect bool If True, use `self`, rather than the parent Dimension, to index into arrays. A typical use case is when arrays are accessed indirectly via the `condition` expression. `False`

## Examples

Among the other things, ConditionalDimensions are indicated to implement Function subsampling. In the following example, an Operator evaluates the Function `g` and saves its content into `f` every `factor=4` iterations.

``````>>> from devito import Dimension, ConditionalDimension, Function, Eq, Operator
>>> size, factor = 16, 4
>>> i = Dimension(name='i')
>>> ci = ConditionalDimension(name='ci', parent=i, factor=factor)
>>> g = Function(name='g', shape=(size,), dimensions=(i,))
>>> f = Function(name='f', shape=(int(size/factor),), dimensions=(ci,))
>>> op = Operator([Eq(g, 1), Eq(f, g)])``````

The Operator generates the following for-loop (pseudocode)

.. code-block:: C

``````for (int i = i_m; i <= i_M; i += 1) {
g[i] = 1;
if (i%4 == 0) {
f[i / 4] = g[i];
}
}``````

Another typical use case is when one needs to constrain the execution of loop iterations so that certain conditions are honoured. The following artificial example uses ConditionalDimension to guard against out-of-bounds accesses in indirectly accessed arrays.

``````>>> from sympy import And
>>> ci = ConditionalDimension(name='ci', parent=i,
...                           condition=And(g[i] > 0, g[i] < 4, evaluate=False))
>>> f = Function(name='f', shape=(int(size/factor),), dimensions=(ci,))
>>> op = Operator(Eq(f[g[i]], f[g[i]] + 1))``````

The Operator generates the following for-loop (pseudocode)

.. code-block:: C

``````for (int i = i_m; i <= i_M; i += 1) {
if (g[i] > 0 && g[i] < 4) {
f[g[i]] = f[g[i]] + 1;
}
}``````

## Attributes

Name Description
is_Conditional bool(x) -> bool
is_NonlinearDerived bool(x) -> bool