/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    $RCSfile: Subsample.cxx,v $
  Language:  C++
  Date:      $Date: 2005/11/19 16:31:51 $
  Version:   $Revision: 1.11 $

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even 
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

// Software Guide : BeginLatex
//
// \index{itk::Statistics::Subsample}
//
// The \subdoxygen{Statistics}{Subsample} is a derived sample. In other
// words, it requires another \subdoxygen{Statistics}{Sample} object for
// storing measurement vectors. The Subsample class stores a subset of
// instance identifiers from another Sample object.  \emph{Any} Sample's
// subclass can be the source Sample object. You can create a Subsample
// object out of another Subsample object. The Subsample class is useful for
// storing classification results from a test Sample object or for just
// extracting some part of interest in a Sample object. Another good use of
// Subsample is sorting a Sample object. When we use an \doxygen{Image}
// object as the data source, we do not want to change the order of data
// element in the image. However, we sometimes want to sort or
// select data elements according to their order. Statistics algorithms for
// this purpose accepts only Subsample objects as inputs. Changing the order
// in a Subsample object does not change the order of the source sample.
//
// To use a Subsample object, we include the header files for
// the class itself and a Sample class. We will use the
// \subdoxygen{Statistics}{ListSample} as the input sample.
//
// Software Guide : EndLatex 


// Software Guide : BeginCodeSnippet
#include "itkListSample.h"
#include "itkSubsample.h"
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// We need another header for measurement vectors. We are going to use
// the \doxygen{Vector} class in this example. 
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
#include "itkVector.h"
// Software Guide : EndCodeSnippet

int main()
{
  // Software Guide : BeginLatex
  //
  // The following code snippet will create a ListSample object
  // with three-component float measurement vectors and put three
  // measurement vectors into the list.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef itk::Vector< float, 3 > MeasurementVectorType;
  typedef itk::Statistics::ListSample< MeasurementVectorType > SampleType;
  SampleType::Pointer sample = SampleType::New();
  MeasurementVectorType mv;
  mv[0] = 1.0;
  mv[1] = 2.0;
  mv[2] = 4.0;
  
  sample->PushBack(mv);

  mv[0] = 2.0;
  mv[1] = 4.0;
  mv[2] = 5.0;
  sample->PushBack(mv);
  
  mv[0] = 3.0;
  mv[1] = 8.0;
  mv[2] = 6.0;
  sample->PushBack(mv);
  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // To create a Subsample instance, we define the type of the Subsample with
  // the source sample type, in this case, the previously defined
  // \code{SampleType}. As usual, after that, we call the \code{New()} method
  // to create an instance. We must plug in the source sample, \code{sample},
  // using the \code{SetSample()} method. However, with regard to data
  // elements, the Subsample is empty. We specify which data elements, among
  // the data elements in the Sample object, are part of the
  // Subsample. There are two ways of doing that. First, if we want to
  // include every data element (instance) from the sample, we simply call
  // the \code{InitializeWithAllInstances()} method like the following:
  //
  // \small
  // \begin{verbatim}
  //   subsample->InitializeWithAllInstances();
  // \end{verbatim}
  // \normalsize
  //
  // This method is useful when we want to create a Subsample
  // object for sorting all the data elements in a Sample
  // object. However, in most cases, we want to include only a subset of
  // a Sample object. For this purpose, we use the
  // \code{AddInstance(instance identifier)} method in this example. In
  // the following code snippet, we include only the first and last
  // instance in our subsample object from the three instances
  // of the Sample class.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef itk::Statistics::Subsample< SampleType > SubsampleType;
  SubsampleType::Pointer subsample = SubsampleType::New();
  subsample->SetSample( sample );
  
  subsample->AddInstance( 0UL );
  subsample->AddInstance( 2UL );
  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // The Subsample is ready for use. The following code snippet
  // shows how to use \code{Iterator} interfaces. 
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  SubsampleType::Iterator iter = subsample->Begin();
  while ( iter != subsample->End() )
    {
    std::cout << "instance identifier = " << iter.GetInstanceIdentifier() 
              << "\t measurement vector = " 
              << iter.GetMeasurementVector() 
              << "\t frequency = " 
              << iter.GetFrequency()
              << std::endl;
    ++iter;
    }
  // Software Guide : EndCodeSnippet

  
  // Software Guide : BeginLatex
  //
  // As mentioned earlier, the instances in a Subsample can be sorted without
  // changing the order in the source Sample. For this purpose, the Subsample
  // provides an additional instance indexing scheme. The indexing scheme is
  // just like the instance identifiers for the Sample. The index is an
  // integer value starting at 0, and the last value is one less than the
  // number of all instances in a Subsample. The \code{Swap(0, 1)} method,
  // for example, swaps two instance identifiers of the first data element
  // and the second element in the Subsample. Internally, the \code{Swap()}
  // method changes the instance identifiers in the first and second
  // position. Using indices, we can print out the effects of the
  // \code{Swap()} method. We use the
  // \code{GetMeasurementVectorByIndex(index)} to get the measurement vector
  // at the index position. However, if we want to use the common methods of
  // Sample that accepts instance identifiers, we call them after we get
  // the instance identifiers using \code{GetInstanceIdentifier(index)}
  // method.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  subsample->Swap(0, 1);

  for ( int index = 0 ; index < subsample->Size() ; ++index )
    {
    std::cout << "instance identifier = " 
              << subsample->GetInstanceIdentifier(index) 
              << "\t measurement vector = " 
              << subsample->GetMeasurementVectorByIndex(index) 
              << std::endl;
    }
  // Software Guide : EndCodeSnippet
  
  // Software Guide : BeginLatex
  //
  // Since we are using a ListSample object as the source sample, the
  // following code snippet will return the same value (2) for the
  // \code{Size()} and the \code{GetTotalFrequency()} methods. However, if we
  // used a Histogram object as the source sample, the two return
  // values might be different because a Histogram allows varying
  // frequency values for each instance.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  std::cout << "Size = " << subsample->Size() << std::endl;
  std::cout << "Total frequency = " 
            << subsample->GetTotalFrequency() << std::endl;
  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // If we want to remove all instances that are associated with the
  // Subsample, we call the \code{Clear()} method. After this invocation, the
  // \code{Size()} and the \code{GetTotalFrequency()} methods return 0.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  subsample->Clear();
  std::cout << "Size = " << subsample->Size() << std::endl;
  std::cout << "Total frequency = " 
            << subsample->GetTotalFrequency() << std::endl;
  // Software Guide : EndCodeSnippet
  
  return 0;
}
