pyAgrum-nightly 2.3.0.9.dev202512061764412981__cp310-abi3-macosx_11_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. pyagrum/__init__.py +165 -0
  2. pyagrum/_pyagrum.so +0 -0
  3. pyagrum/bnmixture/BNMInference.py +268 -0
  4. pyagrum/bnmixture/BNMLearning.py +376 -0
  5. pyagrum/bnmixture/BNMixture.py +464 -0
  6. pyagrum/bnmixture/__init__.py +60 -0
  7. pyagrum/bnmixture/notebook.py +1058 -0
  8. pyagrum/causal/_CausalFormula.py +280 -0
  9. pyagrum/causal/_CausalModel.py +436 -0
  10. pyagrum/causal/__init__.py +81 -0
  11. pyagrum/causal/_causalImpact.py +356 -0
  12. pyagrum/causal/_dSeparation.py +598 -0
  13. pyagrum/causal/_doAST.py +761 -0
  14. pyagrum/causal/_doCalculus.py +361 -0
  15. pyagrum/causal/_doorCriteria.py +374 -0
  16. pyagrum/causal/_exceptions.py +95 -0
  17. pyagrum/causal/_types.py +61 -0
  18. pyagrum/causal/causalEffectEstimation/_CausalEffectEstimation.py +1175 -0
  19. pyagrum/causal/causalEffectEstimation/_IVEstimators.py +718 -0
  20. pyagrum/causal/causalEffectEstimation/_RCTEstimators.py +132 -0
  21. pyagrum/causal/causalEffectEstimation/__init__.py +46 -0
  22. pyagrum/causal/causalEffectEstimation/_backdoorEstimators.py +774 -0
  23. pyagrum/causal/causalEffectEstimation/_causalBNEstimator.py +324 -0
  24. pyagrum/causal/causalEffectEstimation/_frontdoorEstimators.py +396 -0
  25. pyagrum/causal/causalEffectEstimation/_learners.py +118 -0
  26. pyagrum/causal/causalEffectEstimation/_utils.py +466 -0
  27. pyagrum/causal/notebook.py +171 -0
  28. pyagrum/clg/CLG.py +658 -0
  29. pyagrum/clg/GaussianVariable.py +111 -0
  30. pyagrum/clg/SEM.py +312 -0
  31. pyagrum/clg/__init__.py +63 -0
  32. pyagrum/clg/canonicalForm.py +408 -0
  33. pyagrum/clg/constants.py +54 -0
  34. pyagrum/clg/forwardSampling.py +202 -0
  35. pyagrum/clg/learning.py +776 -0
  36. pyagrum/clg/notebook.py +480 -0
  37. pyagrum/clg/variableElimination.py +271 -0
  38. pyagrum/common.py +60 -0
  39. pyagrum/config.py +319 -0
  40. pyagrum/ctbn/CIM.py +513 -0
  41. pyagrum/ctbn/CTBN.py +573 -0
  42. pyagrum/ctbn/CTBNGenerator.py +216 -0
  43. pyagrum/ctbn/CTBNInference.py +459 -0
  44. pyagrum/ctbn/CTBNLearner.py +161 -0
  45. pyagrum/ctbn/SamplesStats.py +671 -0
  46. pyagrum/ctbn/StatsIndepTest.py +355 -0
  47. pyagrum/ctbn/__init__.py +79 -0
  48. pyagrum/ctbn/constants.py +54 -0
  49. pyagrum/ctbn/notebook.py +264 -0
  50. pyagrum/defaults.ini +199 -0
  51. pyagrum/deprecated.py +95 -0
  52. pyagrum/explain/_ComputationCausal.py +75 -0
  53. pyagrum/explain/_ComputationConditional.py +48 -0
  54. pyagrum/explain/_ComputationMarginal.py +48 -0
  55. pyagrum/explain/_CustomShapleyCache.py +110 -0
  56. pyagrum/explain/_Explainer.py +176 -0
  57. pyagrum/explain/_Explanation.py +70 -0
  58. pyagrum/explain/_FIFOCache.py +54 -0
  59. pyagrum/explain/_ShallCausalValues.py +204 -0
  60. pyagrum/explain/_ShallConditionalValues.py +155 -0
  61. pyagrum/explain/_ShallMarginalValues.py +155 -0
  62. pyagrum/explain/_ShallValues.py +296 -0
  63. pyagrum/explain/_ShapCausalValues.py +208 -0
  64. pyagrum/explain/_ShapConditionalValues.py +126 -0
  65. pyagrum/explain/_ShapMarginalValues.py +191 -0
  66. pyagrum/explain/_ShapleyValues.py +298 -0
  67. pyagrum/explain/__init__.py +81 -0
  68. pyagrum/explain/_explGeneralizedMarkovBlanket.py +152 -0
  69. pyagrum/explain/_explIndependenceListForPairs.py +146 -0
  70. pyagrum/explain/_explInformationGraph.py +264 -0
  71. pyagrum/explain/notebook/__init__.py +54 -0
  72. pyagrum/explain/notebook/_bar.py +142 -0
  73. pyagrum/explain/notebook/_beeswarm.py +174 -0
  74. pyagrum/explain/notebook/_showShapValues.py +97 -0
  75. pyagrum/explain/notebook/_waterfall.py +220 -0
  76. pyagrum/explain/shapley.py +225 -0
  77. pyagrum/lib/__init__.py +46 -0
  78. pyagrum/lib/_colors.py +390 -0
  79. pyagrum/lib/bn2graph.py +299 -0
  80. pyagrum/lib/bn2roc.py +1026 -0
  81. pyagrum/lib/bn2scores.py +217 -0
  82. pyagrum/lib/bn_vs_bn.py +605 -0
  83. pyagrum/lib/cn2graph.py +305 -0
  84. pyagrum/lib/discreteTypeProcessor.py +1102 -0
  85. pyagrum/lib/discretizer.py +58 -0
  86. pyagrum/lib/dynamicBN.py +390 -0
  87. pyagrum/lib/explain.py +57 -0
  88. pyagrum/lib/export.py +84 -0
  89. pyagrum/lib/id2graph.py +258 -0
  90. pyagrum/lib/image.py +387 -0
  91. pyagrum/lib/ipython.py +307 -0
  92. pyagrum/lib/mrf2graph.py +471 -0
  93. pyagrum/lib/notebook.py +1821 -0
  94. pyagrum/lib/proba_histogram.py +552 -0
  95. pyagrum/lib/utils.py +138 -0
  96. pyagrum/pyagrum.py +31495 -0
  97. pyagrum/skbn/_MBCalcul.py +242 -0
  98. pyagrum/skbn/__init__.py +49 -0
  99. pyagrum/skbn/_learningMethods.py +282 -0
  100. pyagrum/skbn/_utils.py +297 -0
  101. pyagrum/skbn/bnclassifier.py +1014 -0
  102. pyagrum_nightly-2.3.0.9.dev202512061764412981.dist-info/LICENSE.md +12 -0
  103. pyagrum_nightly-2.3.0.9.dev202512061764412981.dist-info/LICENSES/LGPL-3.0-or-later.txt +304 -0
  104. pyagrum_nightly-2.3.0.9.dev202512061764412981.dist-info/LICENSES/MIT.txt +18 -0
  105. pyagrum_nightly-2.3.0.9.dev202512061764412981.dist-info/METADATA +145 -0
  106. pyagrum_nightly-2.3.0.9.dev202512061764412981.dist-info/RECORD +107 -0
  107. pyagrum_nightly-2.3.0.9.dev202512061764412981.dist-info/WHEEL +4 -0
pyagrum/ctbn/CIM.py ADDED
@@ -0,0 +1,513 @@
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
+
41
+ from typing import Dict, Optional, Union, List
42
+
43
+ import numpy
44
+ import pyagrum
45
+
46
+ """
47
+ This file contains the CIM class (Conditional Intensity Matrix).
48
+ """
49
+
50
+
51
+ class CIM:
52
+ """
53
+ This class is used to represent a CIM (random variables and parameters of transition time).
54
+ A CIM is mainly a pyagrum.Tensor that contains the parameters of an exponential distribution.
55
+ This class contains also contains the ``amalgamation`` operator, used for merging CIMs into one.
56
+
57
+ Notes
58
+ -----
59
+ A static string ``DELIMITER`` is used to differentiate between the current state of the variable and its next state.
60
+ <V_name><DELIMITER>i : starting node
61
+ <V_name><DELIMITER>j : ending node
62
+
63
+ Parameters
64
+ ----------
65
+ pot : pyagrum.Tensor | None
66
+ Defines the new CIM using existing tensor.
67
+ """
68
+
69
+ DELIMITER = "#"
70
+ _pot: pyagrum.Tensor
71
+
72
+ def __init__(self, pot=None):
73
+ if pot is None:
74
+ self._pot = pyagrum.Tensor()
75
+ else:
76
+ self._pot = pyagrum.Tensor(pot)
77
+ self._recordVars()
78
+
79
+ def __getitem__(self, i):
80
+ return self._pot[i]
81
+
82
+ def __setitem__(self, i, v):
83
+ self._pot[i] = v
84
+
85
+ def __mul__(self: "CIM", cimY: "CIM") -> "CIM":
86
+ return self.amalgamate(cimY)
87
+
88
+ def __repr__(self):
89
+ return self._pot.__repr__()
90
+
91
+ def __str__(self):
92
+ return self.__repr__()
93
+
94
+ def add(self, v: pyagrum.DiscreteVariable) -> "CIM":
95
+ """
96
+ Add a new variable to the CIM.
97
+
98
+ Parameters
99
+ ----------
100
+ v : pyagrum.DiscreteVariable
101
+ Variable to add.
102
+
103
+ Returns
104
+ -------
105
+ CIM
106
+ A reference to the CIM.
107
+ """
108
+ if not self._pot.contains(v):
109
+ self._pot.add(v)
110
+ self._recordVars()
111
+ return self
112
+
113
+ def remove(self, v: pyagrum.DiscreteVariable) -> "CIM":
114
+ """
115
+ Removes a variable from the CIM. Only for parent variables.
116
+
117
+ Parameters
118
+ ----------
119
+ v : pyagrum.DiscreteVariable
120
+ Variable to remove.
121
+
122
+ Returns
123
+ -------
124
+ CIM
125
+ A reference to the CIM.
126
+
127
+ Raises
128
+ ------
129
+ pyagrum.NotFound
130
+ If the variable isn't in the CIM.
131
+ pyagrum.InvalidArgument
132
+ If the variable isn't a parent in the CIM.
133
+ """
134
+ if v not in self.variablesSequence():
135
+ raise pyagrum.NotFound("the variable is not in the CIM")
136
+ elif not self.isParent(v):
137
+ raise pyagrum.InvalidArgument("the variable is not a parent in the CIM")
138
+ else:
139
+ self._pot.remove(v)
140
+ self._recordVars()
141
+ return self
142
+
143
+ def nbrDim(self) -> int:
144
+ """
145
+ Returns
146
+ -------
147
+ int
148
+ The number of variables in the CIM (including v_i and v_j variables).
149
+
150
+ """
151
+ return self._pot.nbrDim()
152
+
153
+ def extract(self, ctxt: Optional[Dict[str, str]]) -> "CIM":
154
+ """
155
+ Creates a new CIM extracted from the current CIM using the instantiation ``ctxt``.
156
+
157
+ Parameters
158
+ ----------
159
+ ctxt : Optional[Dict[str, str]]
160
+ Instantiation of variables.
161
+
162
+ Returns
163
+ -------
164
+ CIM
165
+ The extracted CIM.
166
+ """
167
+ return CIM(self._pot.extract(ctxt))
168
+
169
+ def asTensor(self):
170
+ """
171
+
172
+ Returns
173
+ -------
174
+ pyagrum.Tensor
175
+ a copy of the internal tensor
176
+ """
177
+ return pyagrum.Tensor(self._pot)
178
+
179
+ @property
180
+ def varNames(self):
181
+ """
182
+ Returns
183
+ -------
184
+ List[str]
185
+ A list containing the name of each variable in the CIM.
186
+ """
187
+ # return self._pot.varNames
188
+ return self._pot.names
189
+
190
+ def variablesSequence(self) -> List[pyagrum.DiscreteVariable]:
191
+ """
192
+ Returns
193
+ -------
194
+ List[pyagrum.DiscreteVariable]
195
+ A list containing the sequence of variables of the CIM.
196
+ """
197
+ return self._pot.variablesSequence()
198
+
199
+ def variable(self, arg: int) -> "pyagrum.DiscreteVariable":
200
+ """
201
+ Parameters
202
+ ----------
203
+ arg : int
204
+ Index of the variable in the CIM (i.e its node id).
205
+
206
+ Returns
207
+ -------
208
+ pyagrum.DiscreteVariable
209
+ The variable at index ``arg``.
210
+ """
211
+ return self._pot.variable(arg)
212
+
213
+ def findVar(self, name: str) -> Union[None, pyagrum.DiscreteVariable]:
214
+ """
215
+ Finds a variable in the CIM using its name.
216
+
217
+ Parameters
218
+ ----------
219
+ name : str
220
+ Name of the variable to find.
221
+
222
+ Returns
223
+ -------
224
+ pyagrum.DiscreteVariable | None
225
+ The variable if it is in the CIM.
226
+ """
227
+ v: pyagrum.DiscreteVariable
228
+ for v in self._pot.variablesSequence():
229
+ if v.name() == name:
230
+ return v
231
+ return None
232
+
233
+ def instantiation(self):
234
+ """
235
+ Returns
236
+ -------
237
+ pyagrum.Instantiation
238
+ An Instantiation object using the CIM's tensor.
239
+ """
240
+ return pyagrum.Instantiation(self._pot)
241
+
242
+ def _recordVars(self):
243
+ self._parents = set()
244
+ self._bases = set()
245
+ for v in self.variablesSequence():
246
+ if self.isParent(v):
247
+ self._parents.add(v)
248
+ else:
249
+ self._bases.add(v)
250
+
251
+ @staticmethod
252
+ def varI(name: str) -> str:
253
+ """
254
+ Parameters
255
+ ----------
256
+ name : str
257
+ Name of the variable to format.
258
+
259
+ Returns
260
+ -------
261
+ str
262
+ The name of the variable using {name}{DELIMITER}i format.
263
+ """
264
+ return f"{name}{CIM.DELIMITER}i"
265
+
266
+ @staticmethod
267
+ def varJ(name: str) -> str:
268
+ """
269
+ Parameters
270
+ ----------
271
+ name : str
272
+ Name of the variable to format.
273
+
274
+ Returns
275
+ -------
276
+ str
277
+ The name of the variable using {name}{DELIMITER}j format.
278
+ """
279
+ return f"{name}{CIM.DELIMITER}j"
280
+
281
+ @staticmethod
282
+ def varRadical(v: pyagrum.DiscreteVariable) -> str:
283
+ """
284
+ Parameters
285
+ ----------
286
+ v : pyagrum.DiscreteVariable
287
+ Variable to get name from.
288
+
289
+ Returns
290
+ -------
291
+ str
292
+ The name of the variable (without ``DELIMITER`` formatting).
293
+ """
294
+ if CIM.isParent(v):
295
+ return v.name()
296
+ return v.name()[:-2]
297
+
298
+ @staticmethod
299
+ def isParent(v: pyagrum.DiscreteVariable) -> bool:
300
+ """
301
+ Uses the syntax convention to check if a variable's name is the name of a parent in the CIM.
302
+
303
+ Parameters
304
+ ----------
305
+ v : pyagrum.DiscreteVariable
306
+ Variable to check.
307
+
308
+ Returns
309
+ -------
310
+ bool
311
+ True if ``v``'s name corresponds to the name of a parent in the CIM.
312
+ """
313
+ name = v.name()
314
+ if len(name) < 2:
315
+ return True
316
+ if name[-2] != CIM.DELIMITER:
317
+ return True
318
+ return False
319
+
320
+ def isIM(self) -> bool:
321
+ """
322
+ Returns
323
+ -------
324
+ bool
325
+ True if there is no conditioning variable (parent) in the CIM.
326
+ """
327
+ for v in self.variablesSequence():
328
+ if self.isParent(v):
329
+ return False
330
+ return True
331
+
332
+ def toMatrix(self, ctxt: Optional[Dict[str, str]] = None) -> numpy.array:
333
+ """
334
+ Converts a CIM to a numpy.array matrix.
335
+
336
+ Notes
337
+ -----
338
+ Only works for CIMs with no conditioning variable, or CIMs obtained through amalgamation.
339
+
340
+ Parameters
341
+ ----------
342
+ ctxt : Optional[Dict[str, str]] | None
343
+ Instantiation of variables to use if given.
344
+
345
+ Returns
346
+ ------
347
+ numpy.array
348
+ The CIM as a numpy.array.
349
+ """
350
+ if ctxt is not None:
351
+ q = self.extract(ctxt)
352
+ else:
353
+ q = self
354
+ if not q.isIM():
355
+ raise ValueError("The cim is conditionnal.")
356
+ i = q.instantiation()
357
+ iI = pyagrum.Instantiation()
358
+ iJ = pyagrum.Instantiation()
359
+ for n in sorted(q.varNames): # to be sure of a deterministic order
360
+ v = i.variable(n)
361
+ if n[-1] == "i":
362
+ iI.add(v)
363
+ else:
364
+ iJ.add(v)
365
+
366
+ res = []
367
+ iI.setFirst()
368
+ while not iI.end():
369
+ iJ.setFirst()
370
+ line = []
371
+ while not iJ.end():
372
+ i.setVals(iI)
373
+ i.setVals(iJ)
374
+ line.append(q[i])
375
+ iJ.inc()
376
+ res.append(list(line))
377
+ iI.inc()
378
+
379
+ return numpy.array(res)
380
+
381
+ def fromMatrix(self, mat):
382
+ """
383
+ Fills the CIM with matrix ``mat``.
384
+
385
+ Notes
386
+ -----
387
+ Only works for square-shaped matrixes, if the CIM is not conditional.
388
+
389
+ Parameters
390
+ ----------
391
+ mat : numpy.array
392
+ Matrix to convert into a CIM.
393
+ """
394
+ if not self.isIM():
395
+ raise ValueError("The cim is conditionnal.")
396
+ i = self.instantiation()
397
+ iI = pyagrum.Instantiation()
398
+ iJ = pyagrum.Instantiation()
399
+ siz = 1
400
+ for n in sorted(self.varNames): # to be sure of a deterministic order
401
+ v = i.variable(n)
402
+ if n[-1] == "i":
403
+ iI.add(v)
404
+ siz *= v.domainSize()
405
+ else:
406
+ iJ.add(v)
407
+ if mat.shape != (siz, siz):
408
+ raise AttributeError(f"Shape {mat.shape} should be {(siz, siz)}")
409
+
410
+ iI.setFirst()
411
+ for lin in mat:
412
+ iJ.setFirst()
413
+ for v in lin:
414
+ i.setVals(iI)
415
+ i.setVals(iJ)
416
+ self[i] = v
417
+ iJ.inc()
418
+ iI.inc()
419
+
420
+ def amalgamate(self: "CIM", cimY: "CIM") -> "CIM":
421
+ """
422
+ Amalgamation of 2 CIMs, i.e combine 2 CIMs into one. When manipulating CIMs ``*`` can be used instead.
423
+
424
+ Parameters
425
+ ----------
426
+ cimY : CIM
427
+ CIM to amalgamate self with.
428
+
429
+ Returns
430
+ -------
431
+ CIM
432
+ Amalgamation of the CIMs.
433
+ """
434
+ cimX = self
435
+
436
+ # Checks if either one of the CIM is empty
437
+ if cimX.nbrDim() == 0:
438
+ return CIM(pyagrum.Tensor(cimY._pot))
439
+ if cimY.nbrDim() == 0:
440
+ return CIM(pyagrum.Tensor(cimX._pot))
441
+
442
+ # Names of the non-parent variables from the CIM
443
+ sX = {self.varRadical(v) for v in cimX.variablesSequence() if not self.isParent(v)}
444
+ sY = {self.varRadical(v) for v in cimY.variablesSequence() if not self.isParent(v)}
445
+
446
+ amal = CIM()
447
+
448
+ for v in cimX._bases.union(cimY._bases):
449
+ amal.add(v)
450
+
451
+ # parents of cimY that are bases from cimX
452
+ pXinY = set()
453
+ # parents of cimX that are bases from cimY
454
+ pYinX = set()
455
+
456
+ for v in cimX._parents:
457
+ if v.name() not in sY:
458
+ amal.add(v)
459
+ else:
460
+ pYinX.add(v)
461
+
462
+ for v in cimY._parents:
463
+ if v.name() not in sX:
464
+ amal.add(v)
465
+ else:
466
+ pXinY.add(v)
467
+
468
+ amal._recordVars()
469
+
470
+ i = amal.instantiation()
471
+ iX = cimX.instantiation()
472
+ iY = cimY.instantiation()
473
+ # goes over all possible combinations of values of variables and their parents
474
+ i.setFirst()
475
+ while not i.end():
476
+ iX.setVals(i)
477
+ iY.setVals(i)
478
+ for v in pXinY:
479
+ iY.chgVal(v, iX[CIM.varI(v.name())])
480
+ for v in pYinX:
481
+ iX.chgVal(v, iY[CIM.varI(v.name())])
482
+ dX = True
483
+ for v in sX:
484
+ # checks if the variable v from sX changes value over the transition
485
+ if iX[CIM.varI(v)] != iX[CIM.varJ(v)]:
486
+ dX = False
487
+ break
488
+ dY = True
489
+ for v in sY:
490
+ if iY[CIM.varI(v)] != iY[CIM.varJ(v)]:
491
+ dY = False
492
+ break
493
+ if dX and dY: # case where both states don't change
494
+ amal[i] = cimX[iX] + cimY[iY]
495
+ elif dY: # case were one of iX variables changes value but none of iY does
496
+ amal[i] = cimX[iX]
497
+ elif dX: # case were one of iY variables changes value but none of iX does
498
+ amal[i] = cimY[iY]
499
+ else: # case were 2 variables from iX and iY change value at the sime time
500
+ amal[i] = 0
501
+
502
+ i.inc() # next combination of variables
503
+
504
+ return amal
505
+
506
+ def getTensor(self) -> "pyagrum.Tensor":
507
+ """
508
+ Returns
509
+ -------
510
+ pyagrum.Tensor
511
+ A copy of the CIM's tensor
512
+ """
513
+ return pyagrum.Tensor(self._pot)