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 #include <iostream>
20 #include "itkSample.h"
21 #include "itkObjectFactory.h"
22 #include "itkMath.h"
23 
24 namespace itk {
25 namespace Statistics {
26 namespace SampleTest {
27 
28 template <typename TMeasurementVector>
29 class MySample : public Sample< TMeasurementVector >
30 {
31 public:
32   /** Standard class type alias. */
33   using Self = MySample;
34 
35   using Superclass = Sample< TMeasurementVector >;
36 
37   using Pointer = SmartPointer< Self >;
38 
39   using ConstPointer = SmartPointer<const Self>;
40 
41   /** Standard macros */
42   itkTypeMacro(MySample, Sample);
43 
44   /** Method for creation through the object factory. */
45   itkNewMacro(Self);
46 
47   using MeasurementVectorType = typename Superclass::MeasurementVectorType;
48 
49   using TotalAbsoluteFrequencyType = typename Superclass::TotalAbsoluteFrequencyType;
50 
51   using AbsoluteFrequencyType = typename Superclass::AbsoluteFrequencyType;
52 
53   using InstanceIdentifier = typename Superclass::InstanceIdentifier;
54 
55   /** Get the size of the sample (number of measurements) */
Size() const56   InstanceIdentifier Size() const override
57     {
58     return static_cast<InstanceIdentifier>( m_Values.size() );
59     }
60 
61   /** Remove all measurement vectors */
Clear()62   virtual void Clear()
63     {
64     m_Values.clear();
65     }
66 
67 
68   /** Get the measurement associated with a particular
69    * InstanceIdentifier. */
70   const MeasurementVectorType &
GetMeasurementVector(InstanceIdentifier id) const71     GetMeasurementVector(InstanceIdentifier id) const override
72     {
73     return m_Values[id];
74     }
75 
76   /** Get the frequency of a measurement specified by instance
77    * identifier. */
GetFrequency(InstanceIdentifier id) const78   AbsoluteFrequencyType GetFrequency(InstanceIdentifier id) const override
79     {
80     return m_Frequencies[id];
81     }
82 
83   /** Get the total frequency of the sample. */
GetTotalFrequency() const84   TotalAbsoluteFrequencyType GetTotalFrequency() const override
85     {
86     TotalAbsoluteFrequencyType sum = NumericTraits< TotalAbsoluteFrequencyType >::ZeroValue();
87     auto itr = m_Frequencies.begin();
88     while( itr != m_Frequencies.end() )
89       {
90       sum += *itr;
91       ++itr;
92       }
93     return sum;
94     }
95 
PrintSelf(std::ostream & os,Indent indent) const96   void PrintSelf(std::ostream& os, Indent indent) const override
97     {
98     Superclass::PrintSelf(os,indent);
99     os << indent << m_Values.size() << std::endl;
100     os << indent << m_Frequencies.size() << std::endl;
101     }
102 
AddMeasurementVector(const MeasurementVectorType & measure,AbsoluteFrequencyType frequency)103   void AddMeasurementVector(
104     const MeasurementVectorType & measure, AbsoluteFrequencyType frequency )
105     {
106     m_Values.push_back( measure );
107     m_Frequencies.push_back( frequency );
108     }
109 
110 private:
111 
112   std::vector< TMeasurementVector >  m_Values;
113 
114   std::vector< AbsoluteFrequencyType >       m_Frequencies;
115 
116 };
117 
118 }
119 }
120 }
itkSampleTest4(int,char * [])121 int itkSampleTest4(int, char* [] )
122 {
123 
124   constexpr unsigned int MeasurementVectorSize = 17;
125 
126   using MeasurementVectorType = std::vector< float >;
127 
128   using SampleType = itk::Statistics::SampleTest::MySample<MeasurementVectorType>;
129 
130   SampleType::Pointer sample = SampleType::New();
131 
132   std::cout << sample->GetNameOfClass() << std::endl;
133   std::cout << sample->SampleType::Superclass::GetNameOfClass() << std::endl;
134 
135   sample->Print(std::cout);
136 
137   sample->SetMeasurementVectorSize( MeasurementVectorSize ); // for code coverage
138 
139   if( sample->GetMeasurementVectorSize() != MeasurementVectorSize )
140     {
141     std::cerr << "GetMeasurementVectorSize() Failed !" << std::endl;
142     return EXIT_FAILURE;
143     }
144 
145   std::cout << sample->Size() << std::endl;
146 
147   MeasurementVectorType measure( MeasurementVectorSize );
148 
149   for( unsigned int i=0; i<MeasurementVectorSize; i++)
150     {
151     measure[i] = 29 * i * i;
152     }
153 
154   using AbsoluteFrequencyType = SampleType::AbsoluteFrequencyType;
155 
156   AbsoluteFrequencyType frequency = 17;
157 
158   sample->AddMeasurementVector( measure, frequency );
159 
160   MeasurementVectorType measureBack = sample->GetMeasurementVector( 0 );
161   AbsoluteFrequencyType frequencyBack = sample->GetFrequency( 0 );
162 
163   if( frequencyBack != frequency )
164     {
165     std::cerr << "Error in GetFrequency()" << std::endl;
166     return EXIT_FAILURE;
167     }
168 
169   for( unsigned int j=0; j<MeasurementVectorSize; j++)
170     {
171     if( itk::Math::NotExactlyEquals(measureBack[j], measure[j]) )
172       {
173       std::cerr << "Error in Set/Get MeasurementVector()" << std::endl;
174       return EXIT_FAILURE;
175       }
176     }
177 
178   std::cout << sample->GetTotalFrequency() << std::endl;
179 
180 
181   try
182     {
183     sample->SetMeasurementVectorSize( MeasurementVectorSize + 5 );
184     std::cerr << "Sample failed to throw an exception when calling SetMeasurementVectorSize()" << std::endl;
185     return EXIT_FAILURE;
186     }
187   catch( itk::ExceptionObject & excp )
188     {
189     std::cout << "Expected exception caught: " << excp << std::endl;
190     }
191 
192 
193   // If we call Clear(), now we should be able to change the
194   // MeasurementVectorSize of the Sample:
195   sample->Clear();
196 
197   try
198     {
199     sample->SetMeasurementVectorSize( MeasurementVectorSize + 5 );
200     }
201   catch( itk::ExceptionObject & excp )
202     {
203     std::cerr << excp << std::endl;
204     return EXIT_FAILURE;
205     }
206 
207   return EXIT_SUCCESS;
208 }
209