# Operators and functions¶

## Arithmetic operators¶

xtensor provides overloads of traditional arithmetic operators for `xexpression`

objects:

- unary
`operator+`

- unary
`operator-`

`operator+`

`operator-`

`operator*`

`operator/`

All these operators are element-wise operators and apply the lazy broadcasting rules explained in a previous section.

```
#incude "xtensor/xarray.hpp"
xt::xarray<int> a = {{1, 2}, {3, 4}};
xt::xarray<int> b = {1, 2};
xt::xarray<int> res = 2 * (a + b);
// => res = {{4, 8}, {8, 12}}
```

## Logical operators¶

xtensor also provides overloads of the logical operators:

`operator!`

`operator||`

`operator&&`

Like arithmetic operators, these logical operators are element-wise operators and apply the lazy broadcasting rules. In addition to these element-wise logical operators, xtensor provides two reducing boolean functions:

`any(E&& e)`

returns`true`

if any of`e`

elements is truthy,`false`

otherwise.`all(E&& e)`

returns`true`

if all alements of`e`

are truthy,`false`

otherwise.

and an element-wise ternary function (similar to the `: ?`

ternary operator):

`where(E&& b, E1&& e&, E2&& e2)`

returns an`xexpression`

whose elements are those of`e1`

when corresponding elements of`b`

are thruthy, and those of`e2`

otherwise.

```
#include "xtensor/xarray.hpp"
xt::xarray<bool> b = { false, true, true, false };
xt::xarray<int> a1 = { 1, 2, 3, 4 };
xt::xarray<int> a2 = { 11, 12, 13, 14 };
xt::xarray<int> res = xt::where(b, a1, a2);
// => res = { 11, 2, 3, 14 }
```

Unlike in `numpy.where`

, `xt::where`

takes full advantage of the lazyness of xtensor.

## Comparison operators¶

xtensor provides overloads of the inequality operators:

`operator<`

`operator<=`

`operator>`

`operator>=`

These overloads of inequality operators are quite different from the standard C++ inequality operators: they are element-wise
operators returning boolean `xexpression`

:

```
#include "xtensor/xarray.hpp"
xt::xarray<int> a1 = { 1, 12, 3, 14 };
xt::xarray<int> a2 = { 11, 2, 13, 4 };
xt::xarray<bool> comp = a1 < a2;
// => comp = { true, false, true, false }
```

However, equality operators are similar to the traditional ones in C++:

`operator==(const E1& e1, const E2& e2)`

returns`true`

if`e1`

and`e2`

hold the same elements.`operator!=(const E1& e1, const E2& e2)`

returns`true`

if`e1`

and`e2`

don’t hold the same elements.

Element-wise equality comparison can be achieved through the `xt::equal`

function.

```
#include "xtensor/xarray.hpp"
xt::xarray<int> a1 = { 1, 2, 3, 4};
xt::xarray<int> a2 = { 11, 12, 3, 4};
bool res = (a1 == a2);
// => res = false
xt::xarray<bool> re = xt::equal(a1, a2);
// => re = { false, false, true, true }
```

## Mathematical functions¶

xtensor provides overloads for many of the standard mathematical functions:

- basic functions:
`abs`

,`remainder`

,`fma`

, … - exponential functions:
`exp`

,`expm1`

,`log`

,`log1p`

, … - power functions:
`pow`

,`sqrt`

,`cbrt`

, … - trigonometric functions:
`sin`

,`cos`

,`tan`

, … - hyperbolic functions:
`sinh`

,`cosh`

,`tanh`

, … - Error and gamma functions:
`erf`

,`erfc`

,`tgamma`

,`lgamma`

, …. - Nearest integer floating point operations:
`ceil`

,`floor`

,`trunc`

, …

See the API reference for a comprehensive list of available functions. Like operators, the mathematical functions are element-wise functions and apply the lazy broadcasting rules.

## Reducers¶

xtensor provides reducers, that is, means for accumulating values of tensor expressions over prescribed axes.
The return value of a reducer is an `xexpression`

with the same shape as the input expression, with the specified
axes removed.

```
#include "xtensor/xarray.hpp"
#include "xtensor/xmath.hpp"
xt::xarray<double> a = ones<double>({3, 2, 4, 6, 5 });
xt::xarray<double> res = xt::sum(a, {1, 3});
// => res.shape() = { 3, 4, 5 };
// => res(0, 0, 0) = 12
```

You can also call the `reduce`

generator with your own reducing function:

```
#include "xtensor/xarray.hpp"
#include "xtensor/xreducer.hpp"
xt::xarray<double> a = some_init_function({3, 2, 4, 6, 5});
xt::xarray<double> res = reduce([](double a, double b) { return a*a + b*b; },
a,
{1, 3});
```

## Universal functions and vectorization¶

xtensor provides utilities to **vectorize any scalar function** (taking multiple scalar arguments) into a function that
will perform on `xexpression`

s, applying the lazy broadcasting rules which we described in a previous section. These
functions are called `xfunction`

s. They are xtensor’s counterpart to numpy’s universal functions.

Actually, all arithmetic and logical operators, inequality operator and mathematical functions we described before are
`xfunction`

s.

The following snippet shows how to vectorize a scalar function taking two arguments:

```
#include "xtensor/xarray.hpp"
#include "xtensor/xvectorize.hpp"
int f(int a, int b)
{
return a + 2 * b;
}
auto vecf = xt::vectorize(f);
xt::xarray<int> a = { 11, 12, 13 };
xt::xarray<int> b = { 1, 2, 3 };
xt::xarray<int> res = vecf(a, b);
// => res = { 13, 16, 19 }
```