Bertini 2 d882924 (2026-10-06 19:56 UTC)
Numerical algebraic geometry library (C++ core)
Loading...
Searching...
No Matches
node.hpp
Go to the documentation of this file.
1//This file is part of Bertini 2.
2//
3//node.hpp is free software: you can redistribute it and/or modify
4//it under the terms of the GNU General Public License as published by
5//the Free Software Foundation, either version 3 of the License, or
6//(at your option) any later version.
7//
8//node.hpp is distributed in the hope that it will be useful,
9//but WITHOUT ANY WARRANTY; without even the implied warranty of
10//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11//GNU General Public License for more details.
12//
13//You should have received a copy of the GNU General Public License
14//along with node.hpp. If not, see <http://www.gnu.org/licenses/>.
15//
16// Copyright(C) Bertini2 Development Team
17//
18// See <http://www.gnu.org/licenses/> for a copy of the license,
19// as well as COPYING. Bertini2 is provided with permitted
20// additional terms in the b2/licenses/ directory.
21
28
29#ifndef BERTINI_NODE_BASE_HPP
30#define BERTINI_NODE_BASE_HPP
31
32
33
34
35#include <iostream>
36#include <string>
37#include <map>
38#include <tuple>
39#include <optional>
40#include <typeinfo>
41
42#include <boost/type_index.hpp>
43
48
49#include <boost/archive/text_oarchive.hpp>
50#include <boost/archive/text_iarchive.hpp>
51#include <boost/serialization/export.hpp>
52#include <boost/serialization/shared_ptr.hpp>
53#include <boost/serialization/vector.hpp>
54#include <boost/serialization/tracking.hpp>
55#include <boost/serialization/base_object.hpp>
56#include <boost/serialization/nvp.hpp>
57
58
59
60
61
62namespace bertini {
63
64 namespace node{
65 class Variable;
66 }
67
69using VariableGroup = std::vector< std::shared_ptr<node::Variable> >;
70
72using SubstitutionMap = std::map< std::string, std::shared_ptr<node::Node> >;
73
74
75
83
84
85namespace node{
86
96enum PrintPrecedence : unsigned {
97 PrecSum = 10,
102};
103
113class Node : public VisitableBase<>, public std::enable_shared_from_this<Node>
114{
115public:
116
117 virtual ~Node() = default;
118
120
121
122
135 virtual std::shared_ptr<Node> Simplified() const;
136
154 virtual std::shared_ptr<Node> Subs(SubstitutionMap const& substitutions) const;
155
159 virtual void print(std::ostream& target) const = 0;
160
168 virtual unsigned Precedence() const
169 {
170 return PrecAtom;
171 }
172
181 virtual bool IsLiteralZero() const
182 {
183 return false;
184 }
185
191 virtual bool IsLiteralOne() const
192 {
193 return false;
194 }
195
209 std::size_t Hash() const;
210
221 std::shared_ptr<const void> EvalProgram() const { return eval_program_; }
223 void SetEvalProgram(std::shared_ptr<const void> p) const { eval_program_ = p; }
224
234 virtual bool IsSame(Node const& other) const;
235
236
244 virtual std::shared_ptr<Node> Differentiate(std::shared_ptr<Variable> const& v = nullptr) const = 0;
245
256 std::shared_ptr<Node> Differentiate(std::shared_ptr<Variable> const& v, unsigned count) const;
257
268 std::shared_ptr<Node> Differentiate(VariableGroup const& vars) const;
269
276 virtual int Degree(std::shared_ptr<Variable> const& v = nullptr) const = 0;
277
278
279
304 std::vector<int> MultiDegree(VariableGroup const& vars) const;
305
308 virtual std::vector<int> MultiDegreeImpl(VariableGroup const& vars) const = 0;
309
316 virtual int Degree(VariableGroup const& vars) const = 0;
317
332 virtual std::shared_ptr<Node> Homogenized(VariableGroup const& vars, std::shared_ptr<Variable> const& homvar) const;
333
339 virtual bool IsHomogeneous(std::shared_ptr<Variable> const& v = nullptr) const = 0;
340
346 virtual bool IsHomogeneous(VariableGroup const& vars) const = 0;
347
349
355 bool IsPolynomial(std::shared_ptr<Variable> const&v = nullptr) const;
356
357
363 bool IsPolynomial(VariableGroup const&v) const;
364
365
366
367
368
369
370protected:
373 mutable std::optional<std::size_t> structural_hash_;
374
377 mutable std::shared_ptr<const void> eval_program_;
378
381 virtual std::size_t HashImpl() const;
382
384 static void HashCombine(std::size_t& seed, std::size_t value)
385 {
386 seed ^= value + 0x9e3779b97f4a7c15ULL + (seed << 6) + (seed >> 2);
387 }
388
389
390
392
393private:
394 friend std::ostream& operator<<(std::ostream & out, const Node& N);
395
397
398 template <typename Archive>
399 void serialize(Archive& ar, const unsigned /*version*/) {
401 }
402
403}; // re: class node
404
408 inline std::ostream& operator<<(std::ostream & out, const Node& N)
409 {
410 N.print(out);
411 return out;
412 }
413
415 inline std::ostream& operator<<(std::ostream & out, const std::shared_ptr<Node>& N)
416 {
417 N->print(out);
418 return out;
419 }
420
428 inline std::string PrintIn(Node const& N, PrintDialect dialect)
429 {
430 std::ostringstream out;
431 SetDialect(out, dialect);
432 N.print(out);
433 return out.str();
434 }
435
438 inline std::string PrintClassic(Node const& N) { return PrintIn(N, PrintDialect::Classic); }
439
448 inline std::string PrintPython(Node const& N, bool exact)
449 {
451 }
452
453
469 std::shared_ptr<Node> Intern(std::shared_ptr<Node> const& candidate);
470
471
472 } // re: namespace node
473} // re: namespace bertini
474
475
476
477#endif
478/* defined(BERTINI_NODE_BASE_HPP) */
The base class for visitable types.
Definition visitable.hpp:87
An interface for all nodes in a function tree, and for a function object as well.
Definition node.hpp:114
bool IsPolynomial(VariableGroup const &v) const
Check if a Node is polynomial – it has degree at least 0.
virtual std::shared_ptr< Node > Homogenized(VariableGroup const &vars, std::shared_ptr< Variable > const &homvar) const
Homogenize a tree, returning a NEW homogenized tree (functional / non-mutating).
virtual std::size_t HashImpl() const
Compute this node's structural hash.
virtual unsigned Precedence() const
The printing precedence of this node, deciding parenthesization.
Definition node.hpp:168
virtual bool IsLiteralZero() const
Is this node the literal constant 0?
Definition node.hpp:181
bool IsPolynomial(std::shared_ptr< Variable > const &v=nullptr) const
Check if a Node is polynomial – it has degree at least 0.
std::shared_ptr< const void > EvalProgram() const
Opaque, lazily-populated cache of a compiled evaluator for this expression.
Definition node.hpp:221
virtual int Degree(std::shared_ptr< Variable > const &v=nullptr) const =0
Compute the degree, optionally with respect to a single variable.
static void HashCombine(std::size_t &seed, std::size_t value)
Combine an extra value into a running hash (boost::hash_combine recipe).
Definition node.hpp:384
virtual ~Node()=default
virtual int Degree(VariableGroup const &vars) const =0
Compute the overall degree with respect to a variable group.
virtual bool IsHomogeneous(std::shared_ptr< Variable > const &v=nullptr) const =0
Check for homogeneity, absolutely with respect to all variables, including path variables and all oth...
virtual std::vector< int > MultiDegreeImpl(VariableGroup const &vars) const =0
Per-node-type multidegree.
std::optional< std::size_t > structural_hash_
Memoized structural hash (computed on first Hash() call; nodes are immutable so it never needs invali...
Definition node.hpp:373
virtual std::shared_ptr< Node > Simplified() const
Functionally simplify this tree, returning a NEW simplified tree.
std::shared_ptr< Node > Differentiate(VariableGroup const &vars) const
Differentiate with respect to each variable in a group, in sequence.
void SetEvalProgram(std::shared_ptr< const void > p) const
Stash a compiled evaluator for this expression (type-erased; see EvalProgram()).
Definition node.hpp:223
virtual bool IsHomogeneous(VariableGroup const &vars) const =0
Check for homogeneity, with respect to a variable group.
std::shared_ptr< Node > Differentiate(std::shared_ptr< Variable > const &v, unsigned count) const
Differentiate repeatedly with respect to a single variable.
virtual bool IsLiteralOne() const
Is this node the literal constant 1?
Definition node.hpp:191
virtual std::shared_ptr< Node > Differentiate(std::shared_ptr< Variable > const &v=nullptr) const =0
Compute the derivative with respect to a single variable.
friend std::ostream & operator<<(std::ostream &out, const Node &N)
a single layer of indirection, though which to call the overridden virtual print() method which must ...
Definition node.hpp:408
virtual void print(std::ostream &target) const =0
Virtual method for printing Nodes to arbitrary output streams.
std::shared_ptr< const void > eval_program_
Opaque compiled-evaluator cache (a system-layer StraightLineProgram for [this]); see EvalProgram().
Definition node.hpp:377
std::vector< int > MultiDegree(VariableGroup const &vars) const
Compute the multidegree with respect to a variable group.
std::size_t Hash() const
Memoized structural hash of this node.
friend class boost::serialization::access
Definition node.hpp:396
virtual bool IsSame(Node const &other) const
Order-sensitive structural equality, shallow given interned children.
virtual std::shared_ptr< Node > Subs(SubstitutionMap const &substitutions) const
Symbolically substitute variables, returning a NEW tree.
Represents variable leaves in the function tree.
Definition variable.hpp:48
Forward declarations for types in the node:: namespace.
Definition canonical.hpp:56
void register_derived_node_types(Archive &ar)
Register all concrete Node types with a Boost.Serialization archive.
Definition forward_declares.hpp:84
std::string PrintPython(Node const &N, bool exact)
The Python spelling of a tree: ** for powers.
Definition node.hpp:448
std::ostream & operator<<(std::ostream &out, const Node &N)
a single layer of indirection, though which to call the overridden virtual print() method which must ...
Definition node.hpp:408
std::shared_ptr< Node > Intern(std::shared_ptr< Node > const &candidate)
Hash-cons a freshly-built node: return an existing structurally-equal node if one is live,...
PrintDialect
Who a printed expression is for; selects the operator and constant spellings.
Definition print_dialect.hpp:56
@ PythonReadable
Python str: **, the same constant shapes, readable first.
Definition print_dialect.hpp:58
@ PythonExact
Python repr: **, exact constant spellings that eval rebuilds at full precision.
Definition print_dialect.hpp:59
@ Classic
Bertini 1 input: ^, (re+im*I), all digits.
Definition print_dialect.hpp:57
std::string PrintIn(Node const &N, PrintDialect dialect)
Print a tree in one dialect (see print_dialect.hpp).
Definition node.hpp:428
PrintPrecedence
Operator precedence classes, used to decide parenthesization when printing.
Definition node.hpp:96
@ PrecAtom
Definition node.hpp:101
@ PrecNegate
Definition node.hpp:98
@ PrecPower
Definition node.hpp:100
@ PrecMult
Definition node.hpp:99
@ PrecSum
Definition node.hpp:97
std::string PrintClassic(Node const &N)
The Bertini 1 spelling of a tree: ^ for powers, (re+im*I) for complex constants, every constant with ...
Definition node.hpp:438
void SetDialect(std::ios_base &stream, PrintDialect dialect)
Choose the dialect everything subsequently printed to stream is written in.
Definition print_dialect.hpp:76
Definition algorithm_builder.hpp:36
VariableGroupType
How a variable group participates in homogenization.
Definition node.hpp:78
@ Ungrouped
Variables not assigned to any group.
Definition node.hpp:81
@ Homogeneous
A projective (homogeneous) variable group.
Definition node.hpp:79
@ Affine
An affine variable group (to be homogenized).
Definition node.hpp:80
std::map< std::string, std::shared_ptr< node::Node > > SubstitutionMap
A substitution request for Node::Subs: variable name -> the node to put in its place.
Definition node.hpp:72
std::vector< std::shared_ptr< node::Variable > > VariableGroup
An ordered group of variables (the unit of homogenization / variable grouping).
Definition node.hpp:69
Provides an Eigen-like NumTraits struct for querying traits of a number type.
The dialect a function tree is printed in – who the text is for.
Contains the visitable base types.