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 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
|
# Using TiledArray with Eigen {#Tutorial-TiledArray-and-Eigen}
TiledArray has a set of functions that allows you to convert `Array` object to and from [Eigen](http://eigen.tuxfamily.org/) matrix objects. The purpose of these functions is to allow users to quickly prototype TiledArray algorithms with inputs from or outputs to Eigen matrices.
Because Eigen is a non-distributed library, these functions are not appropriate for production code in distributed computing environments. Therefore, these functions will throw an exception if the number of MPI processes is greater than one. If you require conversion of Eigen matrices in distributed computing environments, you need to write your own algorithm to collect or distribute matrix data. See the Submatrix Copy section for more information.
# Conversion Functions
## `eigen_to_array()`
Convert an Eigen matrix into a DistArray object.
### Signature
```
template<typename A , typename Derived >
A
TiledArray::eigen_to_array(madness::World & world,
const typename A::trange_type & trange,
const Eigen::MatrixBase< Derived > & matrix)
```
### Description
This function will copy the content of `matrix` into a DistArray object that is tiled according to the `trange` object. The copy operation is done in parallel, and this function will block until all elements of `matrix` have been copied into the result array tiles.
#### Template Parameters
* `A` A DistArray type
* `Derived` The Eigen matrix derived type
#### Parameters
* `world` The world where the array will live
* `trange` The tiled range of the new array
* `matrix` The Eigen matrix to be copied
#### Returns
A DistArray object (of type `A`) that contains a copy of `matrix`
#### Exceptions
`TiledArray::Exception` When world size is greater than 1
### Usage
```
Eigen::MatrixXd matrix(100, 100);
// Fill matrix with data ...
// Create a tiled range for the new array object
std::vector<std::size_t> blocks;
for(std::size_t i = 0ul; i <= 100ul; i += 10ul)
blocks.push_back(i);
std::array<TiledArray::TiledRange1, 2> blocks2 =
{{ TiledArray::TiledRange1(blocks.begin(), blocks.end()),
TiledArray::TiledRange1(blocks.begin(), blocks.end()) }};
TiledArray::TiledRange trange(blocks2.begin(), blocks2.end());
// Create a DistArray from an Eigen matrix.
TiledArray::TArray<double> array = eigen_to_array<TiledArray::TArray<double> >(world, trange, matrix);
```
### Notes
This function will only work in non-distributed environments. If you need to convert an Eigen matrix to a DistArray object, you must implement it yourself. However, you may use eigen_submatrix_to_tensor to make writing such an algorithm easier.
## `array_to_eigen()`
Convert a DistArray object into an Eigen matrix object.
### Signature
```
template<typename T , unsigned int DIM, typename Tile >
Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>
TiledArray::array_to_eigen(const Array< T, DIM, Tile > & array)
```
### Description
This function will block until all tiles of array have been set and copied into the new Eigen matrix. Usage:
### Template Parameters
* `Tile` The tile type of the array
* `Policy` The policy type of the array
#### Parameters
* `array` The array to be converted
#### Exceptions
`TiledArray::Exception` When world size is greater than 1
#### Usage
```
TiledArray::TArray<double> array(world, trange);
// Set tiles of array ...
Eigen::MatrixXd m = array_to_eigen(array);
```
### Note
This function will only work in non-distributed environments. If you need to convert an Array object to an Eigen matrix, you must implement it yourself. However, you may use eigen_submatrix_to_tensor to make writing such an algorithm easier.
# Eigen Interface
Eigen includes a map class which allows external libraries to work with Eigen. TiledArray provides a set of functions for wrapping `Tensor` object with Eigen::Map. These map objects may be used as normal Eigen matrices or vectors.
## `eigen_map()`
Construct an `m x n` `Eigen::Map` object for a given `Tensor` object.
### Signature
```
template <typename T, typename A>
inline Eigen::Map<const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>, Eigen::AutoAlign>
eigen_map(const Tensor<T, A>& tensor, const std::size_t m, const std::size_t n)
template <typename T, typename A>
inline Eigen::Map<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>, Eigen::AutoAlign>
eigen_map(Tensor<T, A>& tensor, const std::size_t m, const std::size_t n)
```
### Description
This function will wrap a `tensor` in an Eigen map object. This object may be used in expressions with other Eigen objects. See [Eigen documentation](http://eigen.tuxfamily.org/dox/TutorialMapClass.html) for more details on Map objects.
#### Template Parameters
* `T` The tensor element type
* `A` The tensor allocator type
#### Parameters
* `tensor` The tensor object
* `m` The number of rows in the result matrix
* `n` The number of columns in the result matrix
#### Returns
An m x n Eigen matrix map for `tensor`
#### Exceptions
`TiledArray::Exception` When `m * n` is not equal to `tensor` size.
### Usage
```
// Construct a tensor object
std::array<std::size_t, 2> size = {{ 10, 10 }};
TiledArray::Tensor<int> tensor(TiledArray::Range(size), 1);
// Construct an Eigen matrix
Eigen::MatrixXi matrix(10, 10);
matrix.fill(1);
// Intialize an Eigen Matrix with a TiledArray tensor.
Eigen::MatrixXi x = matrix + TiledArray::eigen_map(tensor, 10, 10);
```
### Note
The dimensions `m` and `n` do not have to match the dimensions of the tensor object, but they size of the tensor must be equal to the size of the resulting Eigen map object.
## eigen_map()
Construct a `Eigen::Map` object for a given `Tensor` object.
### Signature
```
template <typename T, typename A>
inline Eigen::Map<const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>, Eigen::AutoAlign>
eigen_map(const Tensor<T, A>& tensor)
template <typename T, typename A>
inline Eigen::Map<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>, Eigen::AutoAlign>
eigen_map(Tensor<T, A>& tensor)
```
### Description
This function will wrap a `tensor` in an Eigen map object. This object may be used in expressions with other Eigen objects. See [http://eigen.tuxfamily.org/dox/TutorialMapClass.html Eigen documentation] for more details on Map objects.
#### Template Parameters
* `T` The tensor element type
* `A` The tensor allocator type
#### Parameters
* `tensor` The tensor object
#### Returns
An Eigen matrix map for `tensor` where the number of rows and columns of the matrix match the dimension sizes of the tensor object.
#### Exceptions
`TiledArray::Exception` When `tensor` dimensions are not equal to 2 or 1.
#### Usage
```
// Construct a tensor object
std::array<std::size_t, 2> size = {{ 10, 10 }};
TiledArray::Tensor<int> tensor(TiledArray::Range(size), 1);
// Construct an Eigen matrix
Eigen::MatrixXi matrix(10, 10);
matrix.fill(1);
// Intialize an Eigen Matrix with a TiledArray tensor.
Eigen::MatrixXi x = matrix + TiledArray::eigen_map(tensor);
```
|