Minsky
node_latex.cc
Go to the documentation of this file.
1 /*
2  @copyright Steve Keen 2018
3  @author Russell Standish
4  This file is part of Minsky.
5 
6  Minsky is free software: you can redistribute it and/or modify it
7  under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  Minsky is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with Minsky. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #include "minsky.h"
21 #include "equations.h"
22 #include "userFunction.h"
23 #include "minsky_epilogue.h"
24 using namespace minsky;
25 
26 namespace MathDAG
27 {
28  string latex(double x)
29  {
30  if (abs(x)>0 && (abs(x)>=1e5 || abs(x)<=1e-4))
31  {
32  int exponent=static_cast<int>(log10(abs(x)));
33  if (exponent<0) exponent++;
34  return str(x/pow(10.0,exponent))+"\\times10^{"+str(exponent)+"}";
35  }
36  return str(x);
37  }
38 
39  // named constants for group identities
40 
41  string mathrm(const string& nm)
42  {
43  // process super/sub scripts
44  string::size_type ss;
45  if ((ss=nm.find_first_of("_^"))!=string::npos)
46  return mathrm(nm.substr(0, ss)) + nm[ss] + "{"+mathrm(nm.substr(ss+1))+"}";
47 
48  // process % chars
49  string::size_type pc;
50  if ((pc=nm.find_first_of('%'))!=string::npos)
51  if (pc>0 && nm[pc-1]!='\\')
52  return mathrm(nm.substr(0, pc)) + "\\" + nm[pc] + mathrm(nm.substr(pc+1));
53 
54  // if its a single letter variable, or contains LaTeX codes, process as is
55  if (nm.length()==1 || nm.find('\\')!=string::npos)
56  return nm;
57  return "\\mathrm{"+nm+"}";
58  }
59 
60  namespace
61  {
62  // RAII class that conditionally writes a left parenthesis on
63  // construction, and right parenthesis on destruction
64  struct ParenIf
65  {
66  ostream& o;
67  bool c;
68  ParenIf(ostream& o, bool c): o(o), c(c) {if (c) o<<"\\left(";}
69  ~ParenIf() {if (c) o<<"\\right)";}
70  };
71  }
72 
73  string latexInit(const string& init)
74  {
75  if (init.empty()) return "0";
76  VariableValue v;
77  v.init(init);
78  auto t=cminsky().variableValues.initValue(v);
79  string r;
80  switch (t.rank())
81  {
82  case 0: return str(t[0]);
83  case 1: r="(";
84  for (size_t i=0; i<5 && i<t.size(); ++i)
85  {
86  if (i>0) r+=' ';
87  r+=str(t[i]);
88  }
89  if (t.size()>5)
90  r+="\\ldots";
91  return r+")";
92  default:
93  return "\\ldots"; //TODO can we represent this stuff reasonably?
94  }
95  }
96 
97 
98  ostream& VariableDAG::latex(ostream& o) const
99  {
100  if (type==constant)
101  return o<<init;
102  return o<<mathrm(name);
103  }
104 
105  template <>
107  {
108  return o<<mathrm(name);
109  }
110 
111  template <>
112  ostream& OperationDAG<OperationType::data>::latex(ostream& o) const
113  {
114  checkArg(0,0);
115  return o<<mathrm(name)<<"("<<arguments[0][0]->latex()<<")";
116  }
117 
118  template <>
119  ostream& OperationDAG<OperationType::ravel>::latex(ostream& o) const
120  {
121  o<<mathrm(name);
122  if (!arguments.empty() && !arguments[0].empty())
123  return o<<"("<<arguments[0][0]->latex()<<")";
124  return o;
125  }
126 
127  template <>
128  ostream& OperationDAG<OperationType::add>::latex(ostream& o) const
129  {
130  for (size_t i=0; !arguments.empty() && i<arguments[0].size(); ++i)
131  {
132  checkArg(0,i);
133  if (i>0) o<<"+";
134  o<<arguments[0][i]->latex();
135  }
136  if (arguments.size()>1 && !arguments[0].empty() && !arguments[1].empty()) o<<"+";
137  for (size_t i=0; arguments.size()>1 && i<arguments[1].size(); ++i)
138  {
139  checkArg(1,i);
140  if (i>0) o<<"+";
141  o<<arguments[1][i]->latex();
142  }
143  return o;
144  }
145 
146  template <>
148  {
149  for (size_t i=0; !arguments.empty() && i<arguments[0].size(); ++i)
150  {
151  checkArg(0,i);
152  if (i>0) o<<"+";
153  o<<arguments[0][i]->latex();
154  }
155  if (arguments.size()>1 && !arguments[1].empty())
156  {
157  checkArg(1,0);
158  o<<"-";
159  const ParenIf p(o, (arguments[1].size()>1 ||
160  BODMASlevel() == arguments[1][0]->BODMASlevel()));
161  for (size_t i=0; i<arguments[1].size(); ++i)
162  {
163  checkArg(1,i);
164  if (i>0) o<<"+";
165  o<<arguments[1][i]->latex();
166  }
167  }
168  return o;
169  }
170 
171  template <>
173  {
174  for (size_t i=0; !arguments.empty() && i<arguments[0].size(); ++i)
175  {
176  checkArg(0,i);
177  if (i>0) o<<"\\times ";
178  const ParenIf p(o, arguments[0][i]->BODMASlevel()>BODMASlevel());
179  o<<arguments[0][i]->latex();
180  }
181  if (arguments.size()>1 && !arguments[0].empty() && !arguments[1].empty()) o<<"\\times ";
182  for (size_t i=0; arguments.size()>1 && i<arguments[1].size(); ++i)
183  {
184  checkArg(1,i);
185  if (i>0) o<<"\\times ";
186  const ParenIf p(o, arguments[1][i]->BODMASlevel()>BODMASlevel());
187  o<<arguments[1][i]->latex();
188  }
189  return o;
190  }
191 
192  template <>
194  {
195  if (arguments.empty()) return o;
196  if (arguments.size()>1) o<< "\\frac{";
197  if (arguments[0].empty()) o<<"1";
198  for (size_t i=0; i<arguments[0].size(); ++i)
199  {
200  checkArg(0,i);
201  if (i>0) o<<"\\times ";
202  const ParenIf p(o, i>0 && arguments[0][i]->BODMASlevel()>BODMASlevel());
203  o<<arguments[0][i]->latex();
204  }
205  if (arguments.size()>1)
206  {
207  o<<"}{";
208  if (arguments[1].empty()) o<<"1";
209  for (size_t i=0; i<arguments[1].size(); ++i)
210  {
211  checkArg(1,i);
212  if (i>0) o<<"\\times ";
213  const ParenIf p(o, i>0 && arguments[1][i]->BODMASlevel()>BODMASlevel());
214  o<<arguments[1][i]->latex();
215  }
216  o<<"}";
217  }
218  return o;
219  }
220 
221  template <>
222  ostream& OperationDAG<OperationType::log>::latex(ostream& o) const
223  {
224  checkArg(0,0); checkArg(1,0);
225  return o<<"\\log_{"<<arguments[1][0]->latex()<<"}\\left("<<
226  arguments[0][0]->latex()<<"\\right)";
227  }
228 
229  template <>
230  ostream& OperationDAG<OperationType::pow>::latex(ostream& o) const
231  {
232  checkArg(0,0); checkArg(1,0);
233  {
234  const ParenIf p(o, arguments[0][0]->BODMASlevel()>BODMASlevel());
235  o<<arguments[0][0]->latex();
236  }
237  return o<<"^{"<<arguments[1][0]->latex()<<"}";
238  }
239 
240  template <>
241  ostream& OperationDAG<OperationType::lt>::latex(ostream& o) const
242  {
243  if (!arguments.empty() && !arguments[0].empty() && arguments[0][0])
244  {
245  o<<"\\theta\\left(";
246  if (arguments.size()>1 && !arguments[1].empty() && arguments[1][0])
247  o<<arguments[1][0]->latex()<<"-";
248  else
249  o<<"-";
250  {
251  const ParenIf p(o, arguments[0][0]->BODMASlevel()>1);
252  o<<arguments[0][0]->latex();
253  }
254  o<<"\\right)";
255  }
256  else
257  if (arguments.size()>1 && !arguments[1].empty() && arguments[1][0])
258  o<<"\\theta\\left("<<arguments[1][0]->latex()<<"\\right)";
259  else
260  o<<"0";
261  return o;
262  }
263 
264  template <>
265  ostream& OperationDAG<OperationType::eq>::latex(ostream& o) const
266  {
267  if (!arguments.empty() && !arguments[0].empty() && arguments[0][0])
268  if (arguments.size()>1 && !arguments[1].empty() && arguments[1][0])
269  {
270  o<<"\\delta\\left("<<arguments[0][0]->latex()<<"-";
271  {
272  const ParenIf p(o, arguments[1][0]->BODMASlevel()>BODMASlevel());
273  o<<arguments[1][0]->latex();
274  }
275  o <<"\\right)";
276  }
277  else
278  o<<"\\delta\\left("<<arguments[0][0]->latex()<<"\\right)";
279  else
280  if (arguments.size()>1 && !arguments[1].empty() && arguments[1][0])
281  o<<"\\delta\\left("<<arguments[1][0]->latex()<<"\\right)";
282  else
283  o<<"1";
284  return o;
285  }
286 
287  template <>
288  ostream& OperationDAG<OperationType::le>::latex(ostream& o) const
289  {
290  if ((!arguments.empty() && !arguments[0].empty() && arguments[0][0]) ||
291  (arguments.size()>1 && !arguments[1].empty() && arguments[1][0]))
292  {
295  lt.latex(o);
296  o<<"+";
297  return eq.latex(o);
298  }
299  return o<<"1"<<endl;
300  }
301 
302 
303  template <>
304  ostream& OperationDAG<OperationType::min>::latex(ostream& o) const
305  {
306  if (!arguments.empty() && !arguments[0].empty() && arguments[0][0])
307  if (arguments.size()>1 && !arguments[1].empty() && arguments[1][0])
308  o<<"\\min\\left("<<arguments[0][0]->latex()<<"," <<
309  arguments[1][0]->latex()<<"\\right)";
310  else
311  o<<"\\min\\left("<<arguments[0][0]->latex()<<",0\\right)";
312  else
313  if (arguments.size()>1 && !arguments[1].empty() && arguments[1][0])
314  o<<"\\min\\left("<<arguments[1][0]->latex()<<",0\\right)";
315  else
316  o<<"0";
317  return o;
318  }
319 
320  template <>
321  ostream& OperationDAG<OperationType::max>::latex(ostream& o) const
322  {
323  if (!arguments.empty() && !arguments[0].empty() && arguments[0][0])
324  if (arguments.size()>1 && !arguments[1].empty() && arguments[1][0])
325  o<<"\\max\\left("<<arguments[0][0]->latex()<<"," <<
326  arguments[1][0]->latex()<<"\\right)";
327  else
328  o<<"\\max\\left("<<arguments[0][0]->latex()<<",0\\right)";
329  else
330  if (arguments.size()>1 && !arguments[1].empty() && arguments[1][0])
331  o<<"\\max\\left("<<arguments[1][0]->latex()<<",0\\right)";
332  else
333  o<<"0";
334  return o;
335  }
336 
337  template <>
338  ostream& OperationDAG<OperationType::and_>::latex(ostream& o) const
339  {
340  if (arguments.size()>1 && !arguments[0].empty() && arguments[0][0] &&
341  !arguments[1].empty() && arguments[1][0])
342  o<<"\\theta\\left("<<arguments[0][0]->latex()<<"-0.5\\right)\\theta\\left(" <<
343  arguments[1][0]->latex()<<"-0.5\\right)";
344  else
345  o<<"0";
346  return o;
347  }
348 
349  template <>
350  ostream& OperationDAG<OperationType::or_>::latex(ostream& o) const
351  {
352  if (!arguments.empty() && !arguments[0].empty() && arguments[0][0])
353  if (arguments.size()>1 && !arguments[1].empty() && arguments[1][0])
354  o<<"\\max\\left(\\theta\\left("<<arguments[0][0]->latex()<<"-0.5\\right)," <<
355  "\\theta\\left("<<arguments[1][0]->latex()<<"\\right)\\right)";
356  else
357  o<<"\\theta\\left("<<arguments[0][0]->latex()<<"-0.5\\right)";
358  else
359  if (arguments.size()>1 && !arguments[1].empty() && arguments[1][0])
360  o<<"\\theta\\left("<<arguments[1][0]->latex()<<"-0.5\\right)";
361  else
362  o<<"0";
363  return o;
364  }
365 
366  template <>
367  ostream& OperationDAG<OperationType::not_>::latex(ostream& o) const
368  {
369  if (!arguments.empty() && !arguments[0].empty() && arguments[0][0])
370  o<<"\\left(1-\\theta\\left(0.5-"<<arguments[0][0]->latex()<<"\\right)\\right)";
371  else
372  o<<"1";
373  return o;
374  }
375 
376  template <>
378  {
379  if (!arguments.empty() && !arguments[0].empty() && arguments[0][0] &&
380  arguments.size()>1 && !arguments[1].empty() && arguments[1][0])
381  return o<<"{\\mathrm cov}\\left("<<arguments[0][0]->latex()<<
382  ","<<arguments[1][0]<<"\\right)";
383  return o<<"0";
384  }
385 
386  template <>
388  {
389  if (!arguments.empty() && !arguments[0].empty() && arguments[0][0] &&
390  arguments.size()>1 && !arguments[1].empty() && arguments[1][0])
391  return o<<"\\rho\\left("<<arguments[0][0]->latex()<<
392  ","<<arguments[1][0]<<"\\right)";
393  return o<<"0";
394  }
395 
396  template <>
398  {
399  if (!arguments.empty() && !arguments[0].empty() && arguments[0][0] &&
400  arguments.size()>1 && !arguments[1].empty() && arguments[1][0])
401  return o<<"{\\mathrm{linReg}\\left("<<arguments[0][0]->latex()<<
402  ","<<arguments[1][0]<<"\\right)";
403  return o<<"0";
404  }
405 
406 
407 
408  template <>
409  ostream& OperationDAG<OperationType::size>::latex(ostream& o) const
410  {
411  if (!arguments.empty() && !arguments[0].empty() && arguments[0][0])
412  {
413  size_t dim=numeric_limits<size_t>::max();
414  if (auto op=dynamic_cast<OperationBase*>(state.get()))
415  if (auto vv=arguments[0][0]->result)
416  {
417  for (auto& i: vv->hypercube().xvectors)
418  if (i.name==op->axis)
419  {
420  dim=&i-&vv->hypercube().xvectors.front();
421  break;
422  }
423  if (dim<vv->rank())
424  return o<<"\\dim\\left("<<arguments[0][0]->latex()<<","<<dim<<"\\right)";
425  }
426  return o<<"\\prod_i(\\dim("<<arguments[0][0]->latex()<<",i))";
427  }
428  return o<<"0";
429  }
430 
431  template <>
432  ostream& OperationDAG<OperationType::shape>::latex(ostream& o) const
433  {
434  if (!arguments.empty() && !arguments[0].empty() && arguments[0][0])
435  {
436  return o<<"shape("<<arguments[0][0]->latex()<<")";
437  }
438  return o<<"0";
439  }
440 
441  template <>
442  ostream& OperationDAG<OperationType::mean>::latex(ostream& o) const
443  {
444  if (!arguments.empty() && !arguments[0].empty() && arguments[0][0])
445  {
446  return o<<"\\left\\langle"<<arguments[0][0]->latex()<<"\\right\\rangle";
447  }
448  return o<<"0";
449  }
450 
451  template <>
453  {
454  if (!arguments.empty() && !arguments[0].empty() && arguments[0][0])
455  {
456  return o<<"{\\mathrm median}\\left("<<arguments[0][0]->latex()<<"\\right)";
457  }
458  return o<<"0";
459  }
460 
461  template <>
463  {
464  if (!arguments.empty() && !arguments[0].empty() && arguments[0][0])
465  {
466  return o<<"\\sigma("<<arguments[0][0]->latex()<<")";
467  }
468  return o<<"0";
469  }
470 
471  template <>
473  {
474  if (!arguments.empty() && !arguments[0].empty() && arguments[0][0])
475  {
476  double exponent=1;
477  if (auto op=dynamic_cast<OperationBase*>(state.get()))
478  exponent=op->arg;
479  return o<<"\\left\\langle\\Delta\\left("<<arguments[0][0]->latex()<<"\\right)^"<<exponent<<"\\right\\rangle";
480  }
481  return o<<"0";
482  }
483 
484  template <>
486  {
487  if (!arguments.empty() && !arguments[0].empty() && arguments[0][0])
488  {
489  size_t nBins=1;
490  if (auto op=dynamic_cast<OperationBase*>(state.get()))
491  nBins=op->arg;
492  return o<<"{\\mathrm histogram}\\left("<<arguments[0][0]->latex()<<","<<nBins<<"\\right)";
493  }
494  return o<<"0";
495  }
496 
497 
498  template <>
499  ostream& OperationDAG<OperationType::time>::latex(ostream& o) const
500  {
501  return o<<" t ";
502  }
503 
504  template <>
505  ostream& OperationDAG<OperationType::euler>::latex(ostream& o) const
506  {
507  return o<<" e ";
508  }
509 
510  template <>
511  ostream& OperationDAG<OperationType::pi>::latex(ostream& o) const
512  {
513  return o<<"\\pi ";
514  }
515 
516  template <>
517  ostream& OperationDAG<OperationType::zero>::latex(ostream& o) const
518  {
519  return o<<" 0 ";
520  }
521 
522  template <>
523  ostream& OperationDAG<OperationType::one>::latex(ostream& o) const
524  {
525  return o<<" 1 ";
526  }
527 
528  template <>
529  ostream& OperationDAG<OperationType::inf>::latex(ostream& o) const
530  {
531  return o<<"\\infty ";
532  }
533 
534  template <>
536  {
537  checkArg(0,0);
538  return o<<"\\left("<<arguments[0][0]->latex()<<"\\right)\\%";
539  }
540 
541  template <>
542  ostream& OperationDAG<OperationType::copy>::latex(ostream& o) const
543  {
544  checkArg(0,0);
545  return o;
546  }
547 
548  template <>
550  {
551  throw error("shouldn't be executed");
552  }
553 
554  template <>
556  {
557  throw error("derivative operator should not appear in LaTeX output");
558  }
559 
560  template <>
561  ostream& OperationDAG<OperationType::sqrt>::latex(ostream& o) const
562  {
563  checkArg(0,0);
564  return o<<"\\sqrt{"<<arguments[0][0]->latex()<<"}";
565  }
566 
567  template <>
568  ostream& OperationDAG<OperationType::exp>::latex(ostream& o) const
569  {
570  checkArg(0,0);
571  o<<"\\exp\\left("<<arguments[0][0]->latex()<<"\\right)";
572  return o;
573  }
574 
575  template <>
576  ostream& OperationDAG<OperationType::ln>::latex(ostream& o) const
577  {
578  checkArg(0,0);
579  return o<<"\\ln\\left("<<arguments[0][0]->latex()<<"\\right)";
580  }
581 
582  template <>
583  ostream& OperationDAG<OperationType::sin>::latex(ostream& o) const
584  {
585  checkArg(0,0);
586  return o<<"\\sin\\left("<<arguments[0][0]->latex()<<"\\right)";
587  }
588 
589  template <>
590  ostream& OperationDAG<OperationType::cos>::latex(ostream& o) const
591  {
592  checkArg(0,0);
593  return o<<"\\cos\\left("<<arguments[0][0]->latex()<<"\\right)";
594  }
595 
596  template <>
597  ostream& OperationDAG<OperationType::tan>::latex(ostream& o) const
598  {
599  checkArg(0,0);
600  return o<<"\\tan\\left("<<arguments[0][0]->latex()<<"\\right)";
601  }
602 
603  template <>
604  ostream& OperationDAG<OperationType::asin>::latex(ostream& o) const
605  {
606  checkArg(0,0);
607  return o<<"\\arcsin\\left("<<arguments[0][0]->latex()<<"\\right)";
608  }
609 
610  template <>
611  ostream& OperationDAG<OperationType::acos>::latex(ostream& o) const
612  {
613  checkArg(0,0);
614  return o<<"\\arccos\\left("<<arguments[0][0]->latex()<<"\\right)";
615  }
616 
617  template <>
618  ostream& OperationDAG<OperationType::atan>::latex(ostream& o) const
619  {
620  checkArg(0,0);
621  return o<<"\\arctan\\left("<<arguments[0][0]->latex()<<"\\right)";
622  }
623 
624  template <>
625  ostream& OperationDAG<OperationType::sinh>::latex(ostream& o) const
626  {
627  checkArg(0,0);
628  return o<<"\\sinh\\left("<<arguments[0][0]->latex()<<"\\right)";
629  }
630 
631  template <>
632  ostream& OperationDAG<OperationType::cosh>::latex(ostream& o) const
633  {
634  checkArg(0,0);
635  return o<<"\\cosh\\left("<<arguments[0][0]->latex()<<"\\right)";
636  }
637 
638  template <>
639  ostream& OperationDAG<OperationType::tanh>::latex(ostream& o) const
640  {
641  checkArg(0,0);
642  return o<<"\\tanh\\left("<<arguments[0][0]->latex()<<"\\right)";
643  }
644 
645  template <>
646  ostream& OperationDAG<OperationType::abs>::latex(ostream& o) const
647  {
648  checkArg(0,0);
649  return o<<"\\left|"<<arguments[0][0]->latex()<<"\\right|";
650  }
651 
652  template <>
653  ostream& OperationDAG<OperationType::floor>::latex(ostream& o) const
654  {
655  checkArg(0,0);
656  return o<<"\\left\\lfloor"<<arguments[0][0]->latex()<<"\\right\\rfloor)";
657  }
658 
659  template <>
660  ostream& OperationDAG<OperationType::frac>::latex(ostream& o) const
661  {
662  checkArg(0,0);
663  return o<<"\\mathrm{frac}("<<arguments[0][0]->latex()<<")";
664  }
665 
666  template <>
667  ostream& OperationDAG<OperationType::Gamma>::latex(ostream& o) const
668  {
669  checkArg(0,0);
670  return o<<"\\Gamma\\left("<<arguments[0][0]->latex()<<"\\right)";
671  }
672 
673  template <>
675  {
676  checkArg(0,0);
677  return o<<"\\psi^{\\left("<<arguments[1][0]->latex()<<"\\right)}\\left("<<arguments[0][0]->latex()<<"\\right)";
678  }
679 
680  template <>
681  ostream& OperationDAG<OperationType::fact>::latex(ostream& o) const
682  {
683  checkArg(0,0);
684  return o<<"\\left("<<arguments[0][0]->latex()<<"\\right)!";
685  }
686 
687  template <>
689  {
690  auto desc=mathrm(dynamic_cast<UserFunction&>(*state).description());
691  if (arguments.empty() || arguments[0].empty())
692  return o<<desc<<"()";
693  if (arguments.size()<2 || arguments[1].empty())
694  return o<<desc<<"\\left("<<arguments[0][0]->latex()<<"\\right)";
695  return o<<desc<<"\\left("<<arguments[0][0]->latex()<<","<<arguments[1][0]->latex()<<"\\right)";
696  }
697 
698  template <>
699  ostream& OperationDAG<OperationType::sum>::latex(ostream& o) const
700  {
701  checkArg(0,0);
702  return o<<"\\sum_i("<<arguments[0][0]->latex()<<")_i";
703  }
704 
705  template <>
707  {
708  checkArg(0,0);
709  return o<<"\\prod_i("<<arguments[0][0]->latex()<<")_i";
710  }
711 
712  template <>
714  {
715  checkArg(0,0);
716  return o<<"\\min_i("<<arguments[0][0]->latex()<<")_i";
717  }
718 
719  template <>
721  {
722  checkArg(0,0);
723  return o<<"\\max_i("<<arguments[0][0]->latex()<<")_i";
724  }
725 
726  template <>
728  {
729  checkArg(0,0);
730  return o<<"\\mathrm{indexOf}(\\min_i("<<arguments[0][0]->latex()<<")_i)";
731  }
732 
733  template <>
735  {
736  checkArg(0,0);
737  return o<<"\\mathrm{indexOf}(\\max_i("<<arguments[0][0]->latex()<<")_i)";
738  }
739 
740  template <>
741  ostream& OperationDAG<OperationType::any>::latex(ostream& o) const
742  {
743  checkArg(0,0);
744  return o<<"\\theta\\left(\\sum_i\\theta\\left(\\left("<<arguments[0][0]->latex()<<"\\right)_i-0.5\\right)\\right)";
745  }
746 
747  template <>
748  ostream& OperationDAG<OperationType::all>::latex(ostream& o) const
749  {
750  checkArg(0,0);
751  return o<<"\\prod_i\\theta\\left(\\left("<<arguments[0][0]->latex()<<"\\right)_i-0.5\\right)";
752  }
753 
754  template <>
756  {
757  checkArg(0,0);
758  return o<<"\\left[\\sum_{j=0}^i\\left("<<arguments[0][0]->latex()<<"\\right)_i\\right])";
759  }
760 
761  template <>
763  {
764  checkArg(0,0);
765  return o<<"\\left[\\prod_{j=0}^i\\left("<<arguments[0][0]->latex()<<"\\right)_i\\right])";
766  }
767 
768  template <>
770  {
771  checkArg(0,0);
772  return o<<"\\left[\\Delta^-\\left("<<arguments[0][0]->latex()<<"\\right)_i\\right])";
773  }
774 
775  template <>
777  {
778  checkArg(0,0);
779  return o<<"\\left[\\Delta^+\\left("<<arguments[0][0]->latex()<<"\\right)_i\\right])";
780  }
781 
782  template <>
784  {
785  checkArg(0,0); checkArg(1,0);
786  return o<<arguments[0][0]->latex()<<"\\cdot"<<arguments[1][0]->latex();
787  }
788 
789  template <>
791  {
792  checkArg(0,0); checkArg(1,0);
793  return o<<arguments[0][0]->latex()<<"\\otimes"<<arguments[1][0]->latex();
794  }
795 
796  template <>
797  ostream& OperationDAG<OperationType::index>::latex(ostream& o) const
798  {
799  checkArg(0,0);
800  return o<<"\\left\\{i: \\left("<<arguments[0][0]->latex()<<"\\right)_i>0.5\\right\\}";
801  }
802 
803  template <>
805  {
806  checkArg(0,0); checkArg(1,0);
807  return o<<"\\left[\\left("<<arguments[0][0]->latex()<<"\\right)_j : j=\\left("<<arguments[1][0]->latex()<<"\\right)_i\\right]";
808  }
809  template <>
810  ostream& OperationDAG<OperationType::meld>::latex(ostream& o) const
811  {
812  checkArg(0,0); checkArg(1,0);
813  return o<<"\\mathrm{meld}\\left("<<arguments[0][0]->latex()<<","<<arguments[1][0]->latex()<<"\\right)";
814  }
815  template <>
816  ostream& OperationDAG<OperationType::merge>::latex(ostream& o) const
817  {
818  checkArg(0,0); checkArg(1,0);
819  return o<<"\\mathrm{merge}\\left("<<arguments[0][0]->latex()<<","<<arguments[1][0]->latex()<<"\\right)";
820  }
821 
822  template <>
823  ostream& OperationDAG<OperationType::slice>::latex(ostream& o) const
824  {
825  checkArg(0,0); checkArg(1,0);
826  double slice=0;
827  if (state)
828  if (auto o=state->operationCast())
829  slice=o->arg;
830  return o<<"\\mathrm{slice}\\left("<<arguments[0][0]->latex()<<","<<slice<<"\\right)";
831  }
832 
833 
834 
835 }
TensorVal initValue(const VariableValue &, std::set< std::string > &visited) const
evaluates the initial value of a given variableValue in the context given by this. visited is used to check for circular definitions
UnitsExpressionWalker pow(const UnitsExpressionWalker &x, const UnitsExpressionWalker &y)
VariableValues variableValues
Definition: minsky.h:200
const std::string & init() const
string latexInit(const string &)
convert an initialisation string into a matlab expression
Definition: node_latex.cc:73
struct TCLcmd::trap::init_t init
Creation and access to the minskyTCL_obj object, which has code to record whenever Minsky&#39;s state cha...
Definition: constMap.h:22
std::string str(T x)
utility function to create a string representation of a numeric type
Definition: str.h:33
const Minsky & cminsky()
const version to help in const correctness
Definition: minsky.h:549
vector< vector< WeakNodePtr > > arguments
Definition: equations.h:219
string latex(double)
convert double to a LaTeX string representing that value
Definition: node_latex.cc:28
ostream & latex(ostream &) const override
writes LaTeX representation of this DAG to the stream
string mathrm(const string &nm)
wraps in if nm has more than one letter - and also takes into account LaTeX subscript/superscripts ...
Definition: node_latex.cc:41