1 // -*- C++ -*-
2 /**
3 * @brief A class which implements the CompositeProcess process
4 *
5 * Copyright 2005-2021 Airbus-EDF-IMACS-ONERA-Phimeca
6 *
7 * This library is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22 #include "openturns/CompositeProcess.hxx"
23 #include "openturns/PersistentObjectFactory.hxx"
24 #include "openturns/Exception.hxx"
25 #include "openturns/WhiteNoise.hxx"
26 #include "openturns/SymbolicFunction.hxx"
27 #include "openturns/ValueFunction.hxx"
28
29 BEGIN_NAMESPACE_OPENTURNS
30
31 CLASSNAMEINIT(CompositeProcess)
32
33 static const Factory<CompositeProcess> Factory_CompositeProcess;
34
CompositeProcess()35 CompositeProcess::CompositeProcess()
36 : ProcessImplementation()
37 , function_(ValueFunction(SymbolicFunction("x", "x^2"), WhiteNoise().getMesh()))
38 , antecedent_(new WhiteNoise())
39 {
40 // Set the mesh
41 setMesh(function_.getOutputMesh());
42 }
43
44 /* Standard constructor */
CompositeProcess(const FieldFunction & function,const Process & antecedent)45 CompositeProcess::CompositeProcess(const FieldFunction & function,
46 const Process & antecedent)
47 : ProcessImplementation()
48 , function_(function)
49 , antecedent_(antecedent)
50 {
51 if (function.getInputDimension() != antecedent_.getOutputDimension())
52 throw InvalidArgumentException(HERE) << "Error: trying to build a CompositeProcess from a Process and a FieldFunction with incompatible dimensions "
53 << "here Process dimension=" << antecedent_.getOutputDimension()
54 << " and FieldFunction input dimension=" << function.getInputDimension();
55 if (function.getInputMesh().getDimension() != antecedent_.getInputDimension())
56 throw InvalidArgumentException(HERE) << "Error: trying to build a CompositeProcess from a Process and a FieldFunction with incompatible mesh dimensions "
57 << "here Process mesh dimension=" << antecedent_.getInputDimension()
58 << " and FieldFunction mesh dimension=" << function.getInputMesh().getDimension();
59 setMesh(function.getOutputMesh());
60 setOutputDimension(function.getOutputDimension());
61 setDescription(function.getOutputDescription());
62 }
63
64 /* Virtual constructor */
clone() const65 CompositeProcess * CompositeProcess::clone() const
66 {
67 return new CompositeProcess(*this);
68 }
69
70 /* String converter */
__repr__() const71 String CompositeProcess::__repr__() const
72 {
73 OSS oss(true);
74 oss << "class=" << CompositeProcess::GetClassName()
75 << " function=" << function_.__repr__()
76 << " antecedent=" << antecedent_.getImplementation()->__repr__();
77 return oss;
78 }
79
__str__(const String &) const80 String CompositeProcess::__str__(const String & ) const
81 {
82 OSS oss(false);
83 oss << getClassName() << "(" << function_.__str__()
84 << "(" << antecedent_.__str__() << ")";
85 return oss;
86 }
87
88 /* Is the underlying a composite process ? */
isComposite() const89 Bool CompositeProcess::isComposite() const
90 {
91 return true;
92 }
93
94 /* Antecedent accessor */
getAntecedent() const95 Process CompositeProcess::getAntecedent() const
96 {
97 return antecedent_;
98 }
99
100 /* Function accessor */
getFunction() const101 FieldFunction CompositeProcess::getFunction() const
102 {
103 return function_;
104 }
105
106 /* Realization accessor */
getRealization() const107 Field CompositeProcess::getRealization() const
108 {
109 Sample values(function_(antecedent_.getRealization().getValues()));
110 values.setDescription(getDescription());
111 Field result(function_.getOutputMesh(), values);
112 return result;
113 }
114
115 /* Compute the next steps of a random walk */
getFuture(const UnsignedInteger stepNumber) const116 TimeSeries CompositeProcess::getFuture(const UnsignedInteger stepNumber) const
117 {
118 /* TimeGrid of the process */
119 RegularGrid timeGrid;
120 try
121 {
122 timeGrid = getTimeGrid();
123 }
124 catch (const InvalidArgumentException &)
125 {
126 throw InternalException(HERE) << "Error: can extend the realization of a process only if defined on a regular grid.";
127 }
128 if (stepNumber == 0) throw InvalidArgumentException(HERE) << "Error: the number of future steps must be positive.";
129 /* TimeGrid associated with the possible future */
130 const Scalar timeStep = timeGrid.getStep();
131 const RegularGrid futurTimeGrid(timeGrid.getEnd(), timeStep, stepNumber);
132 FieldFunction function(function_);
133 if (!function.isActingPointwise())
134 throw NotDefinedException(HERE) << "Error: can only ask future of a process with a point-wise function";
135 function.setInputMesh(futurTimeGrid);
136 return TimeSeries(futurTimeGrid, function(antecedent_.getFuture(stepNumber).getValues()));
137 }
138
139 /* Get the marginal random vector corresponding to indices components */
getMarginal(const Indices & indices) const140 Process CompositeProcess::getMarginal(const Indices & indices) const
141 {
142 return new CompositeProcess(function_.getMarginal(indices), antecedent_.getMarginal(indices));
143 }
144
145 /* Method save() stores the object through the StorageManager */
save(Advocate & adv) const146 void CompositeProcess::save(Advocate & adv) const
147 {
148 ProcessImplementation::save(adv);
149 adv.saveAttribute( "function_", function_ );
150 adv.saveAttribute( "antecedent_", antecedent_ );
151 }
152
153 /* Method load() reloads the object from the StorageManager */
load(Advocate & adv)154 void CompositeProcess::load(Advocate & adv)
155 {
156 ProcessImplementation::load(adv);
157 adv.loadAttribute( "function_", function_ );
158 adv.loadAttribute( "antecedent_", antecedent_ );
159 }
160
161 END_NAMESPACE_OPENTURNS
162