1 /*=========================================================================
2 *
3 * Copyright Insight Software Consortium
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0.txt
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *=========================================================================*/
18
19 // Software Guide : BeginLatex
20 //
21 // \index{itk::Statistics::Subsample}
22 //
23 // The \subdoxygen{Statistics}{Subsample} is a derived sample. In other
24 // words, it requires another \subdoxygen{Statistics}{Sample} object for
25 // storing measurement vectors. The Subsample class stores a subset of
26 // instance identifiers from another Sample object. \emph{Any} Sample's
27 // subclass can be the source Sample object. You can create a Subsample
28 // object out of another Subsample object. The Subsample class is useful for
29 // storing classification results from a test Sample object or for just
30 // extracting some part of interest in a Sample object. Another good use of
31 // Subsample is sorting a Sample object. When we use an \doxygen{Image}
32 // object as the data source, we do not want to change the order of data
33 // elements in the image. However, we sometimes want to sort or
34 // select data elements according to their order. Statistics algorithms for
35 // this purpose accepts only Subsample objects as inputs. Changing the order
36 // in a Subsample object does not change the order of the source sample.
37 //
38 // To use a Subsample object, we include the header files for
39 // the class itself and a Sample class. We will use the
40 // \subdoxygen{Statistics}{ListSample} as the input sample.
41 //
42 // Software Guide : EndLatex
43
44
45 // Software Guide : BeginCodeSnippet
46 #include "itkListSample.h"
47 #include "itkSubsample.h"
48 // Software Guide : EndCodeSnippet
49
50 // Software Guide : BeginLatex
51 //
52 // We need another header for measurement vectors. We are going to use
53 // the \doxygen{Vector} class in this example.
54 //
55 // Software Guide : EndLatex
56
57 // Software Guide : BeginCodeSnippet
58 #include "itkVector.h"
59 // Software Guide : EndCodeSnippet
60
main()61 int main()
62 {
63 // Software Guide : BeginLatex
64 //
65 // The following code snippet will create a ListSample object
66 // with three-component float measurement vectors and put three
67 // measurement vectors into the list.
68 //
69 // Software Guide : EndLatex
70
71 // Software Guide : BeginCodeSnippet
72 using MeasurementVectorType = itk::Vector< float, 3 >;
73 using SampleType = itk::Statistics::ListSample< MeasurementVectorType >;
74 SampleType::Pointer sample = SampleType::New();
75 MeasurementVectorType mv;
76 mv[0] = 1.0;
77 mv[1] = 2.0;
78 mv[2] = 4.0;
79
80 sample->PushBack(mv);
81
82 mv[0] = 2.0;
83 mv[1] = 4.0;
84 mv[2] = 5.0;
85 sample->PushBack(mv);
86
87 mv[0] = 3.0;
88 mv[1] = 8.0;
89 mv[2] = 6.0;
90 sample->PushBack(mv);
91 // Software Guide : EndCodeSnippet
92
93 // Software Guide : BeginLatex
94 //
95 // To create a Subsample instance, we define the type of the Subsample with
96 // the source sample type, in this case, the previously defined
97 // \code{SampleType}. As usual, after that, we call the \code{New()} method
98 // to create an instance. We must plug in the source sample, \code{sample},
99 // using the \code{SetSample()} method. However, with regard to data
100 // elements, the Subsample is empty. We specify which data elements, among
101 // the data elements in the Sample object, are part of the
102 // Subsample. There are two ways of doing that. First, if we want to
103 // include every data element (instance) from the sample, we simply call
104 // the \code{InitializeWithAllInstances()} method like the following:
105 //
106 // \small
107 // \begin{verbatim}
108 // subsample->InitializeWithAllInstances();
109 // \end{verbatim}
110 // \normalsize
111 //
112 // This method is useful when we want to create a Subsample
113 // object for sorting all the data elements in a Sample
114 // object. However, in most cases, we want to include only a subset of
115 // a Sample object. For this purpose, we use the
116 // \code{AddInstance(instance identifier)} method in this example. In
117 // the following code snippet, we include only the first and last
118 // instance in our subsample object from the three instances
119 // of the Sample class.
120 //
121 // Software Guide : EndLatex
122
123 // Software Guide : BeginCodeSnippet
124 using SubsampleType = itk::Statistics::Subsample< SampleType >;
125 SubsampleType::Pointer subsample = SubsampleType::New();
126 subsample->SetSample( sample );
127
128 subsample->AddInstance( 0UL );
129 subsample->AddInstance( 2UL );
130 // Software Guide : EndCodeSnippet
131
132 // Software Guide : BeginLatex
133 //
134 // The Subsample is ready for use. The following code snippet
135 // shows how to use \code{Iterator} interfaces.
136 //
137 // Software Guide : EndLatex
138
139 // Software Guide : BeginCodeSnippet
140 SubsampleType::Iterator iter = subsample->Begin();
141 while ( iter != subsample->End() )
142 {
143 std::cout << "instance identifier = " << iter.GetInstanceIdentifier()
144 << "\t measurement vector = "
145 << iter.GetMeasurementVector()
146 << "\t frequency = "
147 << iter.GetFrequency()
148 << std::endl;
149 ++iter;
150 }
151 // Software Guide : EndCodeSnippet
152
153
154 // Software Guide : BeginLatex
155 //
156 // As mentioned earlier, the instances in a Subsample can be sorted without
157 // changing the order in the source Sample. For this purpose, the Subsample
158 // provides an additional instance indexing scheme. The indexing scheme is
159 // just like the instance identifiers for the Sample. The index is an
160 // integer value starting at 0, and the last value is one less than the
161 // number of all instances in a Subsample. The \code{Swap(0, 1)} method,
162 // for example, swaps two instance identifiers of the first data element
163 // and the second element in the Subsample. Internally, the \code{Swap()}
164 // method changes the instance identifiers in the first and second
165 // position. Using indices, we can print out the effects of the
166 // \code{Swap()} method. We use the
167 // \code{GetMeasurementVectorByIndex(index)} to get the measurement vector
168 // at the index position. However, if we want to use the common methods of
169 // Sample that accepts instance identifiers, we call them after we get
170 // the instance identifiers using \code{GetInstanceIdentifier(index)}
171 // method.
172 //
173 // Software Guide : EndLatex
174
175 // Software Guide : BeginCodeSnippet
176 subsample->Swap(0, 1);
177
178 for ( int index = 0; index < subsample->Size(); ++index )
179 {
180 std::cout << "instance identifier = "
181 << subsample->GetInstanceIdentifier(index)
182 << "\t measurement vector = "
183 << subsample->GetMeasurementVectorByIndex(index)
184 << std::endl;
185 }
186 // Software Guide : EndCodeSnippet
187
188 // Software Guide : BeginLatex
189 //
190 // Since we are using a ListSample object as the source sample, the
191 // following code snippet will return the same value (2) for the
192 // \code{Size()} and the \code{GetTotalFrequency()} methods. However, if we
193 // used a Histogram object as the source sample, the two return
194 // values might be different because a Histogram allows varying
195 // frequency values for each instance.
196 //
197 // Software Guide : EndLatex
198
199 // Software Guide : BeginCodeSnippet
200 std::cout << "Size = " << subsample->Size() << std::endl;
201 std::cout << "Total frequency = "
202 << subsample->GetTotalFrequency() << std::endl;
203 // Software Guide : EndCodeSnippet
204
205 // Software Guide : BeginLatex
206 //
207 // If we want to remove all instances that are associated with the
208 // Subsample, we call the \code{Clear()} method. After this invocation, the
209 // \code{Size()} and the \code{GetTotalFrequency()} methods return 0.
210 //
211 // Software Guide : EndLatex
212
213 // Software Guide : BeginCodeSnippet
214 subsample->Clear();
215 std::cout << "Size = " << subsample->Size() << std::endl;
216 std::cout << "Total frequency = "
217 << subsample->GetTotalFrequency() << std::endl;
218 // Software Guide : EndCodeSnippet
219
220 return EXIT_SUCCESS;
221 }
222