Files
ThirdParty-6/ParaView-5.0.1/VTK/Examples/Statistics/ExampleKMeansStatistics.cxx

255 lines
7.5 KiB
C++

/*
* Copyright 2008 Sandia Corporation.
* Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
* license for use of this work by or on behalf of the
* U.S. Government. Redistribution and use in source and binary forms, with
* or without modification, are permitted provided that this Notice and any
* statement of authorship are reproduced on all copies.
*/
// .SECTION Thanks
// Thanks to Janine Bennett, Philippe Pebay, and David Thompson from Sandia National Laboratories
// for implementing this test.
#include "vtkDoubleArray.h"
#include "vtkMultiBlockDataSet.h"
#include "vtkStringArray.h"
#include "vtkIdTypeArray.h"
#include "vtkTable.h"
#include "vtkMath.h"
#include "vtkKMeansStatistics.h"
#include "vtkStdString.h"
#include "vtkTimerLog.h"
#include <sstream>
//=============================================================================
int main( int, char *[] )
{
int testStatus = 0;
const int nDim = 4;
int nVals = 50;
// Seed random number generator
vtkMath::RandomSeed( static_cast<int>( vtkTimerLog::GetUniversalTime() ) );
// Generate an input table that contains samples of mutually independent random variables over [0, 1]
vtkTable* inputData = vtkTable::New();
vtkDoubleArray* doubleArray;
int numComponents = 1;
for ( int c = 0; c < nDim; ++ c )
{
std::ostringstream colName;
colName << "coord " << c;
doubleArray = vtkDoubleArray::New();
doubleArray->SetNumberOfComponents( numComponents );
doubleArray->SetName( colName.str().c_str() );
doubleArray->SetNumberOfTuples( nVals );
double x;
for ( int r = 0; r < nVals; ++ r )
{
//x = vtkMath::Gaussian();
x = vtkMath::Random();
doubleArray->SetValue( r, x );
}
inputData->AddColumn( doubleArray );
doubleArray->Delete();
}
vtkTable* paramData = vtkTable::New();
vtkIdTypeArray* paramCluster;
vtkDoubleArray* paramArray;
const int numRuns = 5;
const int numClustersInRun[] = { 5, 2, 3, 4, 5 };
paramCluster = vtkIdTypeArray::New();
paramCluster->SetName( "K" );
for( int curRun = 0; curRun < numRuns; curRun++ )
{
for( int nInRun = 0; nInRun < numClustersInRun[curRun]; nInRun++ )
{
paramCluster->InsertNextValue( numClustersInRun[curRun] );
}
}
paramData->AddColumn( paramCluster );
paramCluster->Delete();
for ( int c = 0; c < 5; ++ c )
{
std::ostringstream colName;
colName << "coord " << c;
paramArray = vtkDoubleArray::New();
paramArray->SetNumberOfComponents( numComponents );
paramArray->SetName( colName.str().c_str() );
double x;
for( int curRun = 0; curRun < numRuns; curRun++ )
{
for( int nInRun = 0; nInRun < numClustersInRun[curRun]; nInRun++ )
{
//x = vtkMath::Gaussian();
x = vtkMath::Random();
paramArray->InsertNextValue( x );
}
}
paramData->AddColumn( paramArray );
paramArray->Delete();
}
// Set k-means statistics algorithm and its input data port
vtkKMeansStatistics* haruspex = vtkKMeansStatistics::New();
// First verify that absence of input does not cause trouble
cout << "## Verifying that absence of input does not cause trouble... ";
haruspex->Update();
cout << "done.\n";
// Prepare first test with data
haruspex->SetInput( vtkStatisticsAlgorithm::INPUT_DATA, inputData );
haruspex->SetColumnStatus( inputData->GetColumnName( 0 ) , 1 );
haruspex->SetColumnStatus( inputData->GetColumnName( 2 ) , 1 );
haruspex->SetColumnStatus( "Testing", 1 );
haruspex->RequestSelectedColumns();
haruspex->SetDefaultNumberOfClusters( 3 );
cout << "## Testing with no input data:"
<< "\n";
// Test Learn and Derive options
haruspex->SetLearnOption( true );
haruspex->SetDeriveOption( true );
haruspex->SetTestOption( false );
haruspex->SetAssessOption( false );
haruspex->Update();
vtkMultiBlockDataSet* outputMetaDS = vtkMultiBlockDataSet::SafeDownCast(
haruspex->GetOutputDataObject( vtkStatisticsAlgorithm::OUTPUT_MODEL ) );
for ( unsigned int b = 0; b < outputMetaDS->GetNumberOfBlocks(); ++ b )
{
vtkTable* outputMeta = vtkTable::SafeDownCast( outputMetaDS->GetBlock( b ) );
if ( b == 0 )
{
vtkIdType testIntValue = 0;
for( vtkIdType r = 0; r < outputMeta->GetNumberOfRows(); r++ )
{
testIntValue += outputMeta->GetValueByName( r, "Cardinality" ).ToInt();
}
cout << "## Computed clusters (cardinality: "
<< testIntValue
<< " / run):\n";
if ( testIntValue != nVals )
{
vtkGenericWarningMacro("Sum of cluster cardinalities is incorrect: "
<< testIntValue
<< " != "
<< nVals
<< ".");
testStatus = 1;
}
}
else
{
cout << "## Ranked cluster: "
<< "\n";
}
outputMeta->Dump();
cout << "\n";
}
haruspex->SetInput( vtkStatisticsAlgorithm::LEARN_PARAMETERS, paramData );
cout << "## Testing with input table:"
<< "\n";
paramData->Dump();
cout << "\n";
// Test Assess option only
haruspex->SetLearnOption( true );
haruspex->SetDeriveOption( true );
haruspex->SetTestOption( false );
haruspex->SetAssessOption( false );
haruspex->Update();
outputMetaDS = vtkMultiBlockDataSet::SafeDownCast(
haruspex->GetOutputDataObject( vtkStatisticsAlgorithm::OUTPUT_MODEL ) );
for ( unsigned int b = 0; b < outputMetaDS->GetNumberOfBlocks(); ++ b )
{
vtkTable* outputMeta = vtkTable::SafeDownCast( outputMetaDS->GetBlock( b ) );
if ( b == 0 )
{
vtkIdType r = 0;
vtkIdType testIntValue = 0;
for( int curRun = 0; curRun < numRuns; curRun++ )
{
testIntValue = 0;
for( int nInRun = 0; nInRun < numClustersInRun[curRun]; nInRun++ )
{
testIntValue += outputMeta->GetValueByName( r, "Cardinality" ).ToInt();
r++;
}
}
if ( r != outputMeta->GetNumberOfRows() )
{
vtkGenericWarningMacro("Inconsistency in number of rows: "
<< r
<< " != "
<< outputMeta->GetNumberOfRows()
<< ".");
testStatus = 1;
}
cout << "## Computed clusters (cardinality: "
<< testIntValue
<< " / run):\n";
if ( testIntValue != nVals )
{
vtkGenericWarningMacro("Sum of cluster cardinalities is incorrect: "
<< testIntValue
<< " != "
<< nVals
<< ".");
testStatus = 1;
}
}
else
{
cout << "## Ranked cluster: "
<< "\n";
}
outputMeta->Dump();
cout << "\n";
}
cout << "=================== ASSESS ==================== " << endl;
vtkMultiBlockDataSet* paramsTables = vtkMultiBlockDataSet::New();
paramsTables->ShallowCopy( outputMetaDS );
haruspex->SetInput( vtkStatisticsAlgorithm::INPUT_MODEL, paramsTables );
// Test Assess option only (do not recalculate nor rederive a model)
haruspex->SetLearnOption( false );
haruspex->SetDeriveOption( false );
haruspex->SetTestOption( false );
haruspex->SetAssessOption( true );
haruspex->Update();
vtkTable* outputData = haruspex->GetOutput();
outputData->Dump();
paramsTables->Delete();
paramData->Delete();
inputData->Delete();
haruspex->Delete();
return testStatus;
}