mirror of
https://github.com/OpenFOAM/ThirdParty-6.git
synced 2025-12-08 06:57:43 +00:00
255 lines
7.5 KiB
C++
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;
|
|
}
|