File: missing.rst

package info (click to toggle)
xtensor 0.25.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 6,476 kB
  • sloc: cpp: 65,302; makefile: 202; python: 171; javascript: 8
file content (126 lines) | stat: -rw-r--r-- 4,176 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
.. Copyright (c) 2016, Johan Mabille, Sylvain Corlay and Wolf Vollprecht

   Distributed under the terms of the BSD 3-Clause License.

   The full license is in the file LICENSE, distributed with this software.

Missing values
==============

*xtensor* handles missing values and provides specialized container types for an optimized support of missing values.

Optional expressions
--------------------

Support of missing values in xtensor is primarily provided through the :cpp:type:`xtl::xoptional`
value type and the :cpp:type:`xt::xtensor_optional` and :cpp:type:`xt::xarray_optional` containers.
In the following example, we instantiate a 2-D tensor with a missing value:

.. code:: cpp

    xt::xtensor_optional<double, 2> m
        {{ 1.0 ,       2.0         },
         { 3.0 , missing<double>() }};

This code is semantically equivalent to

.. code:: cpp

    xt::xtensor<xtl::xoptional<double>, 2> m
        {{ 1.0 ,       2.0         },
         { 3.0 , missing<double>() }};

The :cpp:type:`xt::xtensor_optional` container is optimized to handle missing values.
Internally, instead of holding a single container of optional values, it holds an array of ``double``
and a boolean container where each value occupies a single bit instead of ``sizeof(bool)`` bytes.

The :cpp:type:`xt::xtensor_optional::reference` typedef, which is the return type of
:cpp:func:`~xt::xexpression::operator()` is a reference proxy which can be used as an
lvalue for assigning new values in the array.
It happens to be an instance of :cpp:type:`xtl::xoptional\<T, B\> <xtl::optional>` where ``T`` and
``B`` are actually the reference types of the underlying storage for values and boolean flags.

This technique enables performance improvements in mathematical operations over boolean arrays including SIMD optimizations, and
reduces the memory footprint of optional arrays. It should be transparent to the user.

Operating on missing values
---------------------------

Arithmetic operators and mathematical universal functions are overloaded for optional values so that they can be operated upon in the
same way as regular scalars.

.. code:: cpp

    xt::xtensor_optional<double, 2> a
        {{ 1.0 ,       2.0         },
         { 3.0 , missing<double>() }};

    xt::xtensor<double, 1> b
        { 1.0, 2.0 };

    // ``b`` is broadcasted to match the shape of ``a``
    std::cout << a + b << std::endl;

outputs:

.. code::

    {{  2,   4},
     {  4, N/A}}

Optional assemblies
-------------------

The classes :cpp:type:`xt::xoptional_assembly` and :cpp:type:`xt::xoptional_assembly_adaptor` provide
containers and adaptors holding missing values that are optimized for element-wise operations.
Contrary to :cpp:type:`xt::xtensor_optional` and :cpp:type:`xt::xarray_optional`, the optional
assemblies hold two expressions, one holding the values, the other holding the mask for the missing values.
The difference between :cpp:type:`xt::xoptional_assembly` and :cpp:type:`xt::xoptional_assembly_adaptor`
is that the first one is the owner of the two expressions while the last one holds a reference on at least
one of the two expressions.

.. code:: cpp

    xt::xarray<double> v
        {{ 1.0, 2.0 },
         { 3.0, 4.0 }};

    xt::xarray<bool> hv
        {{ true, true  },
         { true, false }};

    xt::xoptional_assembly<xt::xarray<double>, xt::xarray<bool>> assembly(v, hv);
    std::cout << assembly << std::endl;

outputs:

.. code::

    {{ 1,  2 },
     { 3, N/A}}

Handling expressions with missing values
----------------------------------------

Functions :cpp:func:`xt::has_value(E&& e) <xt::has_value>` and :cpp:func:`xt::value(E&& e) <xt::value>`
return expressions corresponding to the underlying value and flag of optional elements.
When ``e`` is an lvalue, :cpp:func:`xt::has_value(E&& e) <xt::has_value>` and
:cpp:func:`xt::value(E&& e) <xt::value>` are lvalues too.

.. code:: cpp

    xt::xtensor_optional<double, 2> a
        {{ 1.0 ,       2.0         },
         { 3.0 , missing<double>() }};


    xt::xtensor<bool, 2> b = xt::has_value(a);

    std::cout << b << std::endl;

outputs:

.. code::

    {{  true,  true},
     {  true, false}}