aGrUM 3.1.1
a C++ library for (probabilistic) graphical models
O3prmBNWriter_tpl.h
Go to the documentation of this file.
1/****************************************************************************
2 * This file is part of the aGrUM/pyAgrum library. *
3 * *
4 * Copyright (c) 2005-2026 by *
5 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
6 * - Christophe GONZALES(_at_AMU) *
7 * *
8 * The aGrUM/pyAgrum library is free software; you can redistribute it *
9 * and/or modify it under the terms of either : *
10 * *
11 * - the GNU Lesser General Public License as published by *
12 * the Free Software Foundation, either version 3 of the License, *
13 * or (at your option) any later version, *
14 * - the MIT license (MIT), *
15 * - or both in dual license, as here. *
16 * *
17 * (see https://agrum.gitlab.io/articles/dual-licenses-lgplv3mit.html) *
18 * *
19 * This aGrUM/pyAgrum library is distributed in the hope that it will be *
20 * useful, but WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
21 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
26 * OTHER DEALINGS IN THE SOFTWARE. *
27 * *
28 * See LICENCES for more details. *
29 * *
30 * SPDX-FileCopyrightText: Copyright 2005-2026 *
31 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
32 * - Christophe GONZALES(_at_AMU) *
33 * SPDX-License-Identifier: LGPL-3.0-or-later OR MIT *
34 * *
35 * Contact : info_at_agrum_dot_org *
36 * homepage : http://agrum.gitlab.io *
37 * gitlab : https://gitlab.com/agrumery/agrum *
38 * *
39 ****************************************************************************/
40
41#pragma once
42
43
44#include <agrum/PRM/o3prm/O3prmBNWriter.h> // to ease IDE parser
45#ifndef DOXYGEN_SHOULD_SKIP_THIS
46
48
49# define O3PRM_INDENT " "
50
51namespace gum {
52 /*
53 * Default constructor.
54 */
55 template < GUM_Numeric GUM_SCALAR >
57 GUM_CONSTRUCTOR(O3prmBNWriter)
58 }
59
60 /*
61 * Destructor.
62 */
63 template < GUM_Numeric GUM_SCALAR >
65 GUM_DESTRUCTOR(O3prmBNWriter)
66 }
67
68 /*
69 * Writes a bayes net in the given output stream.
70 *
71 * @param output The output stream.
72 * @param bn The bayes net writen in the stream.
73 * @throws IOError Raised if an I/O error occurs.
74 */
75 template < GUM_Numeric GUM_SCALAR >
76 void O3prmBNWriter< GUM_SCALAR >::_doWrite(std::ostream& output,
77 const IBayesNet< GUM_SCALAR >& bn) {
78 if (!output.good()) { GUM_ERROR(IOError, "Input/Output error : stream not writable.") }
79 std::string bnName = bn.propertyWithDefault("name", "");
80 if (bnName.empty()) bnName = "bayesnet";
81
82 output << "class " << bnName << " {" << std::endl;
83
84 for (auto node: bn.nodes()) {
85 output << _extractAttribute_(bn, node) << std::endl;
86 }
87
88 output << "}" << std::endl;
89
90 output << std::endl;
91
92 output.flush();
93
94 if (output.fail()) { GUM_ERROR(IOError, "Writing in the ostream failed.") }
95 }
96
97 template < GUM_Numeric GUM_SCALAR >
99 NodeId node) {
100 std::stringstream str;
101 str << O3PRM_INDENT;
102 str << _extractType_(bn, node) << " ";
103 str << _extractName_(bn, node) << " ";
104 if (bn.parents(node).size() > 0) { str << "dependson " << _extractParents_(bn, node) << " "; }
105 str << " {" << _extractCPT_(bn, node) << "};" << std::endl;
106 return str.str();
107 }
108
109 template < GUM_Numeric GUM_SCALAR >
111 NodeId node) {
112 std::stringstream str;
113 auto var = &(bn.variable(node));
114 for (auto parent: bn.cpt(node).variablesSequence()) {
115 if (var != parent) { str << parent->name() << ", "; }
116 }
117 return str.str().substr(0, str.str().size() - 2);
118 }
119
120 template < GUM_Numeric GUM_SCALAR >
122 NodeId node) {
123 std::stringstream str;
124 bool first = true;
125 Instantiation inst(bn.cpt(node));
126
127 str << "[";
128 if (inst.nbrDim() == 1) {
129 // 1D tensor
130 for (inst.setFirst(); !inst.end(); inst.inc()) {
131 if (!first) {
132 str << ", ";
133 } else {
134 first = false;
135 }
136 str << bn.cpt(node)[inst];
137 }
138 } else {
139 // (>1)D tensor (with parents)
140 Instantiation jnst;
141 for (auto var = inst.variablesSequence().rbegin(); var != inst.variablesSequence().rend();
142 --var) {
143 jnst.add(**var);
144 }
145 inst.setFirst();
146 auto currentval = inst.val(0) + 1;
147 for (jnst.setFirst(); !jnst.end(); jnst.inc()) {
148 inst.setVals(jnst);
149 if (!first) {
150 str << ", ";
151 } else {
152 first = false;
153 }
154 if (currentval != inst.val(0)) { // begins line
155 str << std::endl << O3PRM_INDENT << O3PRM_INDENT;
156 currentval = inst.val(0);
157 }
158 str << bn.cpt(node)[inst];
159 }
160 str << std::endl << O3PRM_INDENT;
161 }
162
163 str << "]";
164 return str.str();
165 }
166
167 template < GUM_Numeric GUM_SCALAR >
169 NodeId node) {
170 switch (bn.variable(node).varType()) {
172 auto double_var = static_cast< const DiscretizedVariable< double >* >(&(bn.variable(node)));
173 return _extractDiscretizedType_< DiscretizedVariable< double > >(double_var);
174 }
175 case gum::VarType::RANGE : {
176 return _extractRangeType_(bn, node);
177 }
178 default : {
179 return _extractLabelizedType_(bn, node);
180 }
181 }
182 }
183
184 template < GUM_Numeric GUM_SCALAR >
186 NodeId node) {
187 const auto& var = static_cast< const RangeVariable& >(bn.variable(node));
188 return std::format("int ({}, {})", var.minVal(), var.maxVal());
189 }
190
191 template < GUM_Numeric GUM_SCALAR >
193 NodeId node) {
194 std::stringstream str;
195 str << "labels(";
196 for (auto l: bn.variable(node).labels()) {
197 str << l << ", ";
198 }
199 return str.str().substr(0, str.str().size() - 2) + ")";
200 }
201
202 template < GUM_Numeric GUM_SCALAR >
203 template < typename VARTYPE >
204 std::string O3prmBNWriter< GUM_SCALAR >::_extractDiscretizedType_(const VARTYPE* var) {
205 std::stringstream str;
206 if (var->ticks().size() >= 3) {
207 str << "real(" << var->ticks()[0];
208 for (size_t i = 1; i < var->ticks().size(); ++i) {
209 str << ", " << var->ticks()[i];
210 }
211 str << ")";
212 return str.str();
213 }
214 GUM_ERROR(InvalidArgument, "discretized variable does not have enough ticks")
215 }
216
217 template < GUM_Numeric GUM_SCALAR >
219 NodeId node) {
220 if (!bn.variable(node).name().empty()) {
221 return bn.variable(node).name();
222 } else {
223 return std::to_string(node);
224 }
225 }
226
227 /*
228 * Writes a bayes net in the file referenced by filePath.
229 * If the file doesn't exist, it is created.
230 * If the file exists, it's content will be erased.
231 *
232 * @param filePath The path to the file used to write the bayes net.
233 * @param bn The bayes net writen in the file.
234 * @throw IOError Raised if an I/O error occurs.
235 */
236 template < GUM_Numeric GUM_SCALAR >
237 void O3prmBNWriter< GUM_SCALAR >::_doWrite(std::string_view filePath,
238 const IBayesNet< GUM_SCALAR >& bn) {
239 std::ofstream output(std::filesystem::path{filePath}, std::ios_base::trunc);
240
241 _doWrite(output, bn);
242
243 output.close();
244
245 if (output.fail()) { GUM_ERROR(IOError, "Writing in the ostream failed.") }
246 }
247
248} /* namespace gum */
249
250#endif // DOXYGEN_SHOULD_SKIP_THIS
Definition file for BIF XML exportation class.
Class for discretized random variable.
Class representing the minimal interface for Bayesian network with no numerical data.
Definition IBayesNet.h:75
Class for assigning/browsing values to tuples of discrete variables.
void setFirst()
Assign the first values to the tuple of the Instantiation.
<agrum/PRM/o3prm/O3prmBNWriter.h>
std::string _extractRangeType_(const IBayesNet< GUM_SCALAR > &bn, NodeId node)
void _doWrite(std::ostream &output, const IBayesNet< GUM_SCALAR > &bn) final
Writes a Bayes net in the given output stream.
std::string _extractDiscretizedType_(const VARTYPE *var)
std::string _extractParents_(const IBayesNet< GUM_SCALAR > &bn, NodeId node)
std::string _extractCPT_(const IBayesNet< GUM_SCALAR > &bn, NodeId node)
~O3prmBNWriter() override
Destructor.
std::string _extractLabelizedType_(const IBayesNet< GUM_SCALAR > &bn, NodeId node)
std::string _extractType_(const IBayesNet< GUM_SCALAR > &bn, NodeId node)
std::string _extractAttribute_(const IBayesNet< GUM_SCALAR > &bn, NodeId node)
std::string _extractName_(const IBayesNet< GUM_SCALAR > &bn, NodeId node)
O3prmBNWriter()
Default constructor.
Defines a discrete random variable over an integer interval.
#define GUM_ERROR(type, msg)
Definition exceptions.h:76
Size NodeId
Type for node ids.
gum is the global namespace for all aGrUM entities
Definition agrum.h:46