aGrUM 2.3.2
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-2025 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-2025 *
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#pragma once
41
42
43#ifndef DOXYGEN_SHOULD_SKIP_THIS
44
46
47# define O3PRM_INDENT " "
48
49namespace gum {
50 /*
51 * Default constructor.
52 */
53 template < typename GUM_SCALAR >
55 GUM_CONSTRUCTOR(O3prmBNWriter)
56 }
57
58 /*
59 * Destructor.
60 */
61 template < typename GUM_SCALAR >
63 GUM_DESTRUCTOR(O3prmBNWriter)
64 }
65
66 /*
67 * Writes a bayes net in the given output stream.
68 *
69 * @param output The output stream.
70 * @param bn The bayes net writen in the stream.
71 * @throws IOError Raised if an I/O error occurs.
72 */
73 template < typename GUM_SCALAR >
74 INLINE void O3prmBNWriter< GUM_SCALAR >::_doWrite(std::ostream& output,
75 const IBayesNet< GUM_SCALAR >& bn) {
76 if (!output.good()) { GUM_ERROR(IOError, "Input/Output error : stream not writable.") }
77 std::string bnName = bn.propertyWithDefault("name", "");
78 if (bnName.empty()) bnName = "bayesnet";
79
80 output << "class " << bnName << " {" << std::endl;
81
82 for (auto node: bn.nodes()) {
83 output << _extractAttribute_(bn, node) << std::endl;
84 }
85
86 output << "}" << std::endl;
87
88 output << std::endl;
89
90 output.flush();
91
92 if (output.fail()) { GUM_ERROR(IOError, "Writing in the ostream failed.") }
93 }
94
95 template < typename GUM_SCALAR >
96 INLINE std::string
98 NodeId node) {
99 std::stringstream str;
100 str << O3PRM_INDENT;
101 str << _extractType_(bn, node) << " ";
102 str << _extractName_(bn, node) << " ";
103 if (bn.parents(node).size() > 0) { str << "dependson " << _extractParents_(bn, node) << " "; }
104 str << " {" << _extractCPT_(bn, node) << "};" << std::endl;
105 return str.str();
106 }
107
108 template < typename GUM_SCALAR >
109 INLINE std::string
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 < typename 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 < typename 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 < typename GUM_SCALAR >
185 INLINE std::string
187 NodeId node) {
188 const auto& var = static_cast< const RangeVariable& >(bn.variable(node));
189 std::stringstream str;
190 str << "int (" << var.minVal() << ", " << var.maxVal() << ")";
191 return str.str();
192 }
193
194 template < typename GUM_SCALAR >
195 INLINE std::string
197 NodeId node) {
198 std::stringstream str;
199 str << "labels(";
200 for (auto l: bn.variable(node).labels()) {
201 str << l << ", ";
202 }
203 return str.str().substr(0, str.str().size() - 2) + ")";
204 }
205
206 template < typename GUM_SCALAR >
207 template < typename VARTYPE >
208 INLINE std::string O3prmBNWriter< GUM_SCALAR >::_extractDiscretizedType_(const VARTYPE* var) {
209 std::stringstream str;
210 if (var->ticks().size() >= 3) {
211 str << "real(" << var->ticks()[0];
212 for (size_t i = 1; i < var->ticks().size(); ++i) {
213 str << ", " << var->ticks()[i];
214 }
215 str << ")";
216 return str.str();
217 }
218 GUM_ERROR(InvalidArgument, "discretized variable does not have enough ticks")
219 }
220
221 template < typename GUM_SCALAR >
223 NodeId node) {
224 if (!bn.variable(node).name().empty()) {
225 return bn.variable(node).name();
226 } else {
227 std::stringstream str;
228 str << node;
229 return str.str();
230 }
231 }
232
233 /*
234 * Writes a bayes net in the file referenced by filePath.
235 * If the file doesn't exist, it is created.
236 * If the file exists, it's content will be erased.
237 *
238 * @param filePath The path to the file used to write the bayes net.
239 * @param bn The bayes net writen in the file.
240 * @throw IOError Raised if an I/O error occurs.
241 */
242 template < typename GUM_SCALAR >
243 INLINE void O3prmBNWriter< GUM_SCALAR >::_doWrite(const std::string& filePath,
244 const IBayesNet< GUM_SCALAR >& bn) {
245 std::ofstream output(filePath.c_str(), std::ios_base::trunc);
246
247 _doWrite(output, bn);
248
249 output.close();
250
251 if (output.fail()) { GUM_ERROR(IOError, "Writing in the ostream failed.") }
252 }
253
254} /* namespace gum */
255
256#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 an bayes net in the given ouput 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:72
Size NodeId
Type for node ids.
gum is the global namespace for all aGrUM entities
Definition agrum.h:46