OTB  6.1.0
Orfeo Toolbox
otbFuzzyVariable.txx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
3  *
4  * This file is part of Orfeo Toolbox
5  *
6  * https://www.orfeo-toolbox.org/
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #ifndef otbFuzzyVariable_txx
22 #define otbFuzzyVariable_txx
23 
24 
25 #include "otbFuzzyVariable.h"
26 #include "otbMacro.h"
27 
28 namespace otb
29 {
30 
31 template <class TLabel, class TPrecision>
33 {}
34 
35 template <class TLabel, class TPrecision>
36 void
38  const PrecisionType & v1,
39  const PrecisionType & v2,
40  const PrecisionType & v3,
41  const PrecisionType & v4)
42 {
43  // Check if values are ordered correctly
44  if( v1>v2 || v2>v3 || v3>v4)
45  itkExceptionMacro(<< "Values have to be v1<=v2<=v3<=v4");
46 
47  // Build the membership parameters
48  ParametersType parameters;
49  parameters[0] = v1;
50  parameters[1] = v2;
51  parameters[2] = v3;
52  parameters[3] = v4;
53  parameters[4] = static_cast<TPrecision>(0);
54  parameters[5] = static_cast<TPrecision>(1);
55 
56  // Insert it in the parameters map
57  m_MembershipFunctions[var]=parameters;
58 
59  // Call modified
60  this->Modified();
61 }
62 
63 template <class TLabel, class TPrecision>
64 void
66  const PrecisionType & v1,
67  const PrecisionType & v2,
68  const PrecisionType & v3,
69  const PrecisionType & v4,
70  const PrecisionType & min,
71  const PrecisionType & max)
72 {
73  // Check if values are ordered correctly
74  if( v1>v2 || v2>v3 || v3>v4)
75  itkExceptionMacro(<< "Values have to be v1<=v2<=v3<=v4");
76  if( min>=max)
77  itkExceptionMacro(<< "Values have to be min<max");
78 
79  // Build the membership parameters
80  ParametersType parameters;
81  parameters[0] = v1;
82  parameters[1] = v2;
83  parameters[2] = v3;
84  parameters[3] = v4;
85  parameters[4] = min;
86  parameters[5] = max;
87 
88  // Insert it in the parameters map
89  m_MembershipFunctions[var]=parameters;
90 
91  // Call modified
92  this->Modified();
93 }
94 
95 template <class TLabel, class TPrecision>
96 void
99 {
100  // Erase one parameter
101  m_MembershipFunctions.erase(var);
102 
103  // Call Modified()
104  this->Modified();
105 }
106 
107 template <class TLabel, class TPrecision>
108 void
111 {
112  // Clear the membership parameters map
113  m_MembershipFunctions.clear();
114 
115  // Call Modified()
116  this->Modified();
117 }
118 
119 
120 template <class TLabel, class TPrecision>
122 ::PrecisionType
124 ::GetMembership(const LabelType & var, const PrecisionType & value) const
125 {
126  // Declare output
128 
129  // Retrieve parameters for the given membership function
130  typename ParametersMapType::const_iterator mapIt = m_MembershipFunctions.find(var);
131 
132  // If var exists in the parameters map
133  if(mapIt!=m_MembershipFunctions.end())
134  {
135  // Retrieve parameters
136  ParametersType parameters = mapIt->second;
137 
138  // Remaining of the code is trapezoidal function
139  if( value < parameters[0] || value >= parameters[3] )
140  {
141  output = parameters[4];
142  }
143  else if( value >= parameters[0]
144  && value < parameters[1] )
145  {
146  if(parameters[1]>parameters[0])
147  {
148  output = static_cast<TPrecision>(parameters[4] + (value - parameters[0])
149  /(parameters[1] - parameters[0])
150  *(parameters[5] - parameters[4]));
151  }
152  else
153  {
154  output = parameters[5];
155  }
156  }
157 
158  if( value >= parameters[1]
159  && value < parameters[2] )
160  {
161  output = parameters[5];
162  }
163 
164  if( value >= parameters[2]
165  && value < parameters[3] )
166  {
167  if(parameters[3]>parameters[2])
168  {
169  output = static_cast<TPrecision>(parameters[4] + (parameters[3] - value)
170  /(parameters[3] - parameters[2])
171  *(parameters[5] - parameters[4]));
172  }
173  else
174  {
175  output = parameters[5];
176  }
177  }
178 
179  }
180 
181  // Return the membership value
182  return output;
183 }
184 
185 template <class TLabel, class TPrecision>
187 ::MembershipValueType
189 ::GetMembership(const PrecisionType & value) const
190 {
191  // Build the output membership map
192  MembershipValueType output;
193 
194  // Walk the membership parameters map
195  for(typename ParametersMapType::const_iterator mapIt = m_MembershipFunctions.begin();
196  mapIt!=m_MembershipFunctions.end(); ++mapIt)
197  {
198  // Compute the membership
199  output[mapIt->first] = this->GetMembership(mapIt->first, value);
200  }
201 
202  // Return output
203  return output;
204 }
205 
206 template <class TLabel, class TPrecision>
208 ::LabelType
210 ::GetMaxVar(const PrecisionType & value) const
211 {
212  // If parameters map is empty, throw an exception
213  if(m_MembershipFunctions.empty())
214  {
215  itkExceptionMacro(<<"Membership parameters map is empty");
216  }
217 
218  // First retrieve all membership values
219  MembershipValueType memberships = this->GetMembership(value);
220 
221  // Define an iterator on the membership parameters map
222  typename MembershipValueType::const_iterator mapIt = memberships.begin();
223 
224  // Look for the higher value
225  LabelType higherVar = mapIt->first;
226  PrecisionType higherVal = mapIt->second;
227  ++mapIt;
228 
229  while(mapIt!=memberships.end())
230  {
231  if(mapIt->second > higherVal)
232  {
233  higherVal = mapIt->second;
234  higherVar = mapIt->first;
235  }
236  ++mapIt;
237  }
238 
239  // Return the higher var
240  return higherVar;
241 }
242 
243 template <class TLabel, class TPrecision>
244 void
246 ::PrintSelf(std::ostream& os, itk::Indent indent) const
247 {
248  Superclass::PrintSelf(os, indent);
249 }
250 
251 template <class TLabel, class TPrecision>
252 std::ostream &
254 ::PrintMembershipValueType(std::ostream & out,
255  const MembershipValueType & labelMap)
256 {
257  // Define an iterator on the label set
258  typedef std::map<TLabel, TPrecision> LabelMapType;
259  typename LabelMapType::const_iterator it = labelMap.begin();
260 
261  // Open the set
262  out<<"{";
263 
264  // Append the set elements
265  while(it != labelMap.end())
266  {
267  out<<it->first<<" : "<<it->second;
268  ++it;
269  if(it != labelMap.end())
270  out<<", ";
271  }
272 
273  // close the set
274  out<<"}";
275 
276  // Return
277  return out;
278 }
279 
280 } // end namespace otb
281 
282 
283 #endif
PrecisionType GetMembership(const LabelType &var, const PrecisionType &value) const
std::map< LabelType, PrecisionType > MembershipValueType
LabelType GetMaxVar(const PrecisionType &value) const
void PrintSelf(std::ostream &os, itk::Indent indent) const ITK_OVERRIDE
void SetMembership(const LabelType &var, const PrecisionType &v1, const PrecisionType &v2, const PrecisionType &v3, const PrecisionType &v4)
TPrecision PrecisionType
Class to represent a fuzzy N-valued variable.
void RemoveMembership(const LabelType &var)
static std::ostream & PrintMembershipValueType(std::ostream &out, const MembershipValueType &membership)