xtensor
Loading...
Searching...
No Matches
xmime.hpp
1/***************************************************************************
2 * Copyright (c) Johan Mabille, Sylvain Corlay and Wolf Vollprecht *
3 * Copyright (c) QuantStack *
4 * *
5 * Distributed under the terms of the BSD 3-Clause License. *
6 * *
7 * The full license is in the file LICENSE, distributed with this software. *
8 ****************************************************************************/
9
10#ifndef XTENSOR_MIME_HPP
11#define XTENSOR_MIME_HPP
12
13#include <cstddef>
14#include <sstream>
15#include <string>
16#include <vector>
17
18#include <nlohmann/json.hpp>
19
20#include "xio.hpp"
21
22namespace xt
23{
24 template <class P, class T>
25 void compute_0d_table(std::stringstream& out, P& /*printer*/, const T& expr)
26 {
27 out << "<table style='border-style:solid;border-width:1px;'><tbody>";
28 out << "<tr><td style='font-family:monospace;'><pre>";
29 out << expr();
30 out << "</pre></td></tr>";
31 out << "</tbody></table>";
32 }
33
34 template <class P>
35 void compute_1d_row(std::stringstream& out, P& printer, const std::size_t& row_idx)
36 {
37 out << "<tr><td style='font-family:monospace;' title='" << row_idx << "'><pre>";
38 printer.print_next(out);
39 out << "</pre></td></tr>";
40 }
41
42 template <class P, class T>
43 void compute_1d_table(std::stringstream& out, P& printer, const T& expr, const std::size_t& edgeitems)
44 {
45 const auto& dim = expr.shape()[0];
46
47 out << "<table style='border-style:solid;border-width:1px;'><tbody>";
48 if (edgeitems == 0 || 2 * edgeitems >= dim)
49 {
50 for (std::size_t row_idx = 0; row_idx < dim; ++row_idx)
51 {
52 compute_1d_row(out, printer, row_idx);
53 }
54 }
55 else
56 {
57 for (std::size_t row_idx = 0; row_idx < edgeitems; ++row_idx)
58 {
59 compute_1d_row(out, printer, row_idx);
60 }
61 out << "<tr><td><center>\u22ee</center></td></tr>";
62 for (std::size_t row_idx = dim - edgeitems; row_idx < dim; ++row_idx)
63 {
64 compute_1d_row(out, printer, row_idx);
65 }
66 }
67 out << "</tbody></table>";
68 }
69
70 template <class P>
71 void compute_2d_element(
72 std::stringstream& out,
73 P& printer,
74 const std::string& idx_str,
75 const std::size_t& row_idx,
76 const std::size_t& column_idx
77 )
78 {
79 out << "<td style='font-family:monospace;' title='(" << idx_str << row_idx << ", " << column_idx
80 << ")'><pre>";
81 printer.print_next(out);
82 out << "</pre></td>";
83 }
84
85 template <class P, class T>
86 void compute_2d_row(
87 std::stringstream& out,
88 P& printer,
89 const T& expr,
90 const std::size_t& edgeitems,
91 const std::string& idx_str,
92 const std::size_t& row_idx
93 )
94 {
95 const auto& dim = expr.shape()[expr.dimension() - 1];
96
97 out << "<tr>";
98 if (edgeitems == 0 || 2 * edgeitems >= dim)
99 {
100 for (std::size_t column_idx = 0; column_idx < dim; ++column_idx)
101 {
102 compute_2d_element(out, printer, idx_str, row_idx, column_idx);
103 }
104 }
105 else
106 {
107 for (std::size_t column_idx = 0; column_idx < edgeitems; ++column_idx)
108 {
109 compute_2d_element(out, printer, idx_str, row_idx, column_idx);
110 }
111 out << "<td><center>\u22ef</center></td>";
112 for (std::size_t column_idx = dim - edgeitems; column_idx < dim; ++column_idx)
113 {
114 compute_2d_element(out, printer, idx_str, row_idx, column_idx);
115 }
116 }
117 out << "</tr>";
118 }
119
120 template <class P, class T, class I>
121 void compute_2d_table(
122 std::stringstream& out,
123 P& printer,
124 const T& expr,
125 const std::size_t& edgeitems,
126 const std::vector<I>& idx
127 )
128 {
129 const auto& dim = expr.shape()[expr.dimension() - 2];
130 const auto& last_dim = expr.shape()[expr.dimension() - 1];
131 std::string idx_str;
132 std::for_each(
133 idx.cbegin(),
134 idx.cend(),
135 [&idx_str](const auto& i)
136 {
137 idx_str += std::to_string(i) + ", ";
138 }
139 );
140
141 std::size_t nb_ellipsis = 2 * edgeitems + 1;
142 if (last_dim <= 2 * edgeitems + 1)
143 {
144 nb_ellipsis = last_dim;
145 }
146
147 out << "<table style='border-style:solid;border-width:1px;'><tbody>";
148 if (edgeitems == 0 || 2 * edgeitems >= dim)
149 {
150 for (std::size_t row_idx = 0; row_idx < dim; ++row_idx)
151 {
152 compute_2d_row(out, printer, expr, edgeitems, idx_str, row_idx);
153 }
154 }
155 else
156 {
157 for (std::size_t row_idx = 0; row_idx < edgeitems; ++row_idx)
158 {
159 compute_2d_row(out, printer, expr, edgeitems, idx_str, row_idx);
160 }
161 out << "<tr>";
162 for (std::size_t column_idx = 0; column_idx < nb_ellipsis; ++column_idx)
163 {
164 if (column_idx == edgeitems && nb_ellipsis != last_dim)
165 {
166 out << "<td><center>\u22f1</center></td>";
167 }
168 else
169 {
170 out << "<td><center>\u22ee</center></td>";
171 }
172 }
173 out << "</tr>";
174 for (std::size_t row_idx = dim - edgeitems; row_idx < dim; ++row_idx)
175 {
176 compute_2d_row(out, printer, expr, edgeitems, idx_str, row_idx);
177 }
178 }
179 out << "</tbody></table>";
180 }
181
182 template <class P, class T, class I>
183 void compute_nd_row(
184 std::stringstream& out,
185 P& printer,
186 const T& expr,
187 const std::size_t& edgeitems,
188 const std::vector<I>& idx
189 )
190 {
191 out << "<tr><td>";
192 compute_nd_table_impl(out, printer, expr, edgeitems, idx);
193 out << "</td></tr>";
194 }
195
196 template <class P, class T, class I>
197 void compute_nd_table_impl(
198 std::stringstream& out,
199 P& printer,
200 const T& expr,
201 const std::size_t& edgeitems,
202 const std::vector<I>& idx
203 )
204 {
205 const auto& displayed_dimension = idx.size();
206 const auto& expr_dim = expr.dimension();
207 const auto& dim = expr.shape()[displayed_dimension];
208
209 if (expr_dim - displayed_dimension == 2)
210 {
211 return compute_2d_table(out, printer, expr, edgeitems, idx);
212 }
213
214 std::vector<I> idx2 = idx;
215 idx2.resize(displayed_dimension + 1);
216
217 out << "<table style='border-style:solid;border-width:1px;'>";
218 if (edgeitems == 0 || 2 * edgeitems >= dim)
219 {
220 for (std::size_t i = 0; i < dim; ++i)
221 {
222 idx2[displayed_dimension] = i;
223 compute_nd_row(out, printer, expr, edgeitems, idx2);
224 }
225 }
226 else
227 {
228 for (std::size_t i = 0; i < edgeitems; ++i)
229 {
230 idx2[displayed_dimension] = i;
231 compute_nd_row(out, printer, expr, edgeitems, idx2);
232 }
233 out << "<tr><td><center>\u22ef</center></td></tr>";
234 for (std::size_t i = dim - edgeitems; i < dim; ++i)
235 {
236 idx2[displayed_dimension] = i;
237 compute_nd_row(out, printer, expr, edgeitems, idx2);
238 }
239 }
240 out << "</table>";
241 }
242
243 template <class P, class T>
244 void compute_nd_table(std::stringstream& out, P& printer, const T& expr, const std::size_t& edgeitems)
245 {
246 if (expr.dimension() == 0)
247 {
248 compute_0d_table(out, printer, expr);
249 }
250 else if (expr.dimension() == 1)
251 {
252 compute_1d_table(out, printer, expr, edgeitems);
253 }
254 else
255 {
256 std::vector<std::size_t> empty_vector;
257 compute_nd_table_impl(out, printer, expr, edgeitems, empty_vector);
258 }
259 }
260
261 template <class E>
262 nlohmann::json mime_bundle_repr_impl(const E& expr)
263 {
264 std::stringstream out;
265
266 std::size_t edgeitems = 0;
267 std::size_t size = compute_size(expr.shape());
268 if (size > static_cast<std::size_t>(print_options::print_options().threshold))
269 {
270 edgeitems = static_cast<std::size_t>(print_options::print_options().edge_items);
271 }
272
273 if (print_options::print_options().precision != -1)
274 {
275 out.precision(print_options::print_options().precision);
276 }
277
278 detail::printer<E> printer(out.precision());
279
280 xstrided_slice_vector slice_vector;
281 detail::recurser_run(printer, expr, slice_vector, edgeitems);
282 printer.init();
283
284 compute_nd_table(out, printer, expr, edgeitems);
285
286 auto bundle = nlohmann::json::object();
287 bundle["text/html"] = out.str();
288 return bundle;
289 }
290
291 template <class F, class CT>
292 class xfunctor_view;
293
294 template <class F, class CT>
295 nlohmann::json mime_bundle_repr(const xfunctor_view<F, CT>& expr)
296 {
297 return mime_bundle_repr_impl(expr);
298 }
299
300 template <class F, class... CT>
301 class xfunction;
302
303 template <class F, class... CT>
304 nlohmann::json mime_bundle_repr(const xfunction<F, CT...>& expr)
305 {
306 return mime_bundle_repr_impl(expr);
307 }
308
309 template <class EC, layout_type L, class SC, class Tag>
310 class xarray_container;
311
312 template <class EC, layout_type L, class SC, class Tag>
313 nlohmann::json mime_bundle_repr(const xarray_container<EC, L, SC, Tag>& expr)
314 {
315 return mime_bundle_repr_impl(expr);
316 }
317
318 template <class EC, std::size_t N, layout_type L, class Tag>
319 class xtensor_container;
320
321 template <class EC, std::size_t N, layout_type L, class Tag>
322 nlohmann::json mime_bundle_repr(const xtensor_container<EC, N, L, Tag>& expr)
323 {
324 return mime_bundle_repr_impl(expr);
325 }
326
327 template <class ET, class S, layout_type L, bool SH, class Tag>
328 class xfixed_container;
329
330 template <class ET, class S, layout_type L, bool SH, class Tag>
331 nlohmann::json mime_bundle_repr(const xfixed_container<ET, S, L, SH, Tag>& expr)
332 {
333 return mime_bundle_repr_impl(expr);
334 }
335
336 template <class F, class CT, class X, class O>
337 class xreducer;
338
339 template <class F, class CT, class X, class O>
340 nlohmann::json mime_bundle_repr(const xreducer<F, CT, X, O>& expr)
341 {
342 return mime_bundle_repr_impl(expr);
343 }
344
345 template <class VE, class FE>
346 class xoptional_assembly;
347
348 template <class VE, class FE>
349 nlohmann::json mime_bundle_repr(const xoptional_assembly<VE, FE>& expr)
350 {
351 return mime_bundle_repr_impl(expr);
352 }
353
354 template <class VEC, class FEC>
355 class xoptional_assembly_adaptor;
356
357 template <class VEC, class FEC>
358 nlohmann::json mime_bundle_repr(const xoptional_assembly_adaptor<VEC, FEC>& expr)
359 {
360 return mime_bundle_repr_impl(expr);
361 }
362
363 template <class CT>
364 class xscalar;
365
366 template <class CT>
367 nlohmann::json mime_bundle_repr(const xscalar<CT>& expr)
368 {
369 return mime_bundle_repr_impl(expr);
370 }
371
372 template <class CT, class X>
373 class xbroadcast;
374
375 template <class CT, class X>
376 nlohmann::json mime_bundle_repr(const xbroadcast<CT, X>& expr)
377 {
378 return mime_bundle_repr_impl(expr);
379 }
380
381 template <class F, class R, class S>
382 class xgenerator;
383
384 template <class F, class R, class S>
385 nlohmann::json mime_bundle_repr(const xgenerator<F, R, S>& expr)
386 {
387 return mime_bundle_repr_impl(expr);
388 }
389
390 template <class CT, class... S>
391 class xview;
392
393 template <class CT, class... S>
394 nlohmann::json mime_bundle_repr(const xview<CT, S...>& expr)
395 {
396 return mime_bundle_repr_impl(expr);
397 }
398
399 template <class CT, class S, layout_type L, class FST>
400 class xstrided_view;
401
402 template <class CT, class S, layout_type L, class FST>
403 nlohmann::json mime_bundle_repr(const xstrided_view<CT, S, L, FST>& expr)
404 {
405 return mime_bundle_repr_impl(expr);
406 }
407
408 template <class CTD, class CTM>
409 class xmasked_view;
410
411 template <class CTD, class CTM>
412 nlohmann::json mime_bundle_repr(const xmasked_view<CTD, CTM>& expr)
413 {
414 return mime_bundle_repr_impl(expr);
415 }
416
417 template <class T, class B>
419
420 template <class T, class B>
421 nlohmann::json mime_bundle_repr(const xmasked_value<T, B>& v)
422 {
423 auto bundle = nlohmann::json::object();
424 std::stringstream tmp;
425 tmp << v;
426 bundle["text/plain"] = tmp.str();
427 return bundle;
428 }
429}
430
431#endif
standard mathematical functions for xexpressions
std::vector< xstrided_slice< std::ptrdiff_t > > xstrided_slice_vector
vector of slices used to build a xstrided_view