mirror of
https://github.com/OpenFOAM/ThirdParty-6.git
synced 2025-12-08 06:57:43 +00:00
792 lines
23 KiB
C++
792 lines
23 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 Philippe Pebay and David Thompson from Sandia National Laboratories
|
|
// for implementing this test.
|
|
|
|
#include "vtkDataObjectCollection.h"
|
|
#include "vtkDoubleArray.h"
|
|
#include "vtkMath.h"
|
|
#include "vtkMultiBlockDataSet.h"
|
|
#include "vtkStringArray.h"
|
|
#include "vtkTable.h"
|
|
#include "vtkTimerLog.h"
|
|
#include "vtkDescriptiveStatistics.h"
|
|
|
|
//=============================================================================
|
|
int main( int, char *[] )
|
|
{
|
|
int testStatus = 0;
|
|
|
|
// ************** Test with 3 columns of input data **************
|
|
|
|
// Input data
|
|
double mingledData[] =
|
|
{
|
|
46,
|
|
45,
|
|
47,
|
|
49,
|
|
46,
|
|
47,
|
|
46,
|
|
46,
|
|
47,
|
|
46,
|
|
47,
|
|
49,
|
|
49,
|
|
49,
|
|
47,
|
|
45,
|
|
50,
|
|
50,
|
|
46,
|
|
46,
|
|
51,
|
|
50,
|
|
48,
|
|
48,
|
|
52,
|
|
54,
|
|
48,
|
|
47,
|
|
52,
|
|
52,
|
|
49,
|
|
49,
|
|
53,
|
|
54,
|
|
50,
|
|
50,
|
|
53,
|
|
54,
|
|
50,
|
|
52,
|
|
53,
|
|
53,
|
|
50,
|
|
51,
|
|
54,
|
|
54,
|
|
49,
|
|
49,
|
|
52,
|
|
52,
|
|
50,
|
|
51,
|
|
52,
|
|
52,
|
|
49,
|
|
47,
|
|
48,
|
|
48,
|
|
48,
|
|
50,
|
|
46,
|
|
48,
|
|
47,
|
|
47,
|
|
};
|
|
|
|
// Test with entire data set
|
|
int nVals1 = 32;
|
|
|
|
vtkDoubleArray* dataset1Arr = vtkDoubleArray::New();
|
|
dataset1Arr->SetNumberOfComponents( 1 );
|
|
dataset1Arr->SetName( "Metric 0" );
|
|
|
|
vtkDoubleArray* dataset2Arr = vtkDoubleArray::New();
|
|
dataset2Arr->SetNumberOfComponents( 1 );
|
|
dataset2Arr->SetName( "Metric 1" );
|
|
|
|
vtkDoubleArray* dataset3Arr = vtkDoubleArray::New();
|
|
dataset3Arr->SetNumberOfComponents( 1 );
|
|
dataset3Arr->SetName( "Metric 2" );
|
|
|
|
for ( int i = 0; i < nVals1; ++ i )
|
|
{
|
|
int ti = i << 1;
|
|
dataset1Arr->InsertNextValue( mingledData[ti] );
|
|
dataset2Arr->InsertNextValue( mingledData[ti + 1] );
|
|
dataset3Arr->InsertNextValue( -1. );
|
|
}
|
|
|
|
vtkTable* datasetTable1 = vtkTable::New();
|
|
datasetTable1->AddColumn( dataset1Arr );
|
|
dataset1Arr->Delete();
|
|
datasetTable1->AddColumn( dataset2Arr );
|
|
dataset2Arr->Delete();
|
|
datasetTable1->AddColumn( dataset3Arr );
|
|
dataset3Arr->Delete();
|
|
|
|
// Pairs of interest
|
|
int nMetrics = 3;
|
|
vtkStdString columns[] =
|
|
{
|
|
"Metric 1",
|
|
"Metric 2",
|
|
"Metric 0"
|
|
};
|
|
|
|
// Reference values
|
|
// Means for metrics 0, 1, and 2, respectively
|
|
double means1[] = { 49.21875 , 49.5, -1. };
|
|
|
|
// Standard deviations for metrics 0, 1, and 2, respectively
|
|
double stdevs1[] = { sqrt( 5.9828629 ), sqrt( 7.548397 ), 0. };
|
|
|
|
// Set descriptive statistics algorithm and its input data port
|
|
vtkDescriptiveStatistics* ds1 = vtkDescriptiveStatistics::New();
|
|
|
|
// First verify that absence of input does not cause trouble
|
|
cout << "\n## Verifying that absence of input does not cause trouble... ";
|
|
ds1->Update();
|
|
cout << "done.\n";
|
|
|
|
// Prepare first test with data
|
|
ds1->SetInput( vtkStatisticsAlgorithm::INPUT_DATA, datasetTable1 );
|
|
datasetTable1->Delete();
|
|
|
|
// Select Columns of Interest
|
|
for ( int i = 0; i< nMetrics; ++ i )
|
|
{
|
|
ds1->AddColumn( columns[i] );
|
|
}
|
|
|
|
// Test Learn, Derive, Test, and Assess options
|
|
ds1->SetLearnOption( true );
|
|
ds1->SetDeriveOption( true );
|
|
ds1->SetAssessOption( true );
|
|
ds1->SetTestOption( true );
|
|
ds1->SignedDeviationsOff();
|
|
ds1->Update();
|
|
|
|
// Get output data and meta tables
|
|
vtkTable* outputData1 = ds1->GetOutput( vtkStatisticsAlgorithm::OUTPUT_DATA );
|
|
vtkMultiBlockDataSet* outputMetaDS1 = vtkMultiBlockDataSet::SafeDownCast( ds1->GetOutputDataObject( vtkStatisticsAlgorithm::OUTPUT_MODEL ) );
|
|
vtkTable* outputPrimary1 = vtkTable::SafeDownCast( outputMetaDS1->GetBlock( 0 ) );
|
|
vtkTable* outputDerived1 = vtkTable::SafeDownCast( outputMetaDS1->GetBlock( 1 ) );
|
|
vtkTable* outputTest1 = ds1->GetOutput( vtkStatisticsAlgorithm::OUTPUT_TEST );
|
|
|
|
cout << "\n## Calculated the following primary statistics for first data set:\n";
|
|
for ( vtkIdType r = 0; r < outputPrimary1->GetNumberOfRows(); ++ r )
|
|
{
|
|
cout << " ";
|
|
for ( int i = 0; i < outputPrimary1->GetNumberOfColumns(); ++ i )
|
|
{
|
|
cout << outputPrimary1->GetColumnName( i )
|
|
<< "="
|
|
<< outputPrimary1->GetValue( r, i ).ToString()
|
|
<< " ";
|
|
}
|
|
|
|
// Verify some of the calculated primary statistics
|
|
if ( fabs ( outputPrimary1->GetValueByName( r, "Mean" ).ToDouble() - means1[r] ) > 1.e-6 )
|
|
{
|
|
vtkGenericWarningMacro("Incorrect mean");
|
|
testStatus = 1;
|
|
}
|
|
cout << "\n";
|
|
}
|
|
|
|
cout << "\n## Calculated the following derived statistics for first data set:\n";
|
|
for ( vtkIdType r = 0; r < outputDerived1->GetNumberOfRows(); ++ r )
|
|
{
|
|
cout << " ";
|
|
for ( int i = 0; i < outputDerived1->GetNumberOfColumns(); ++ i )
|
|
{
|
|
cout << outputDerived1->GetColumnName( i )
|
|
<< "="
|
|
<< outputDerived1->GetValue( r, i ).ToString()
|
|
<< " ";
|
|
}
|
|
|
|
// Verify some of the calculated derived statistics
|
|
if ( fabs ( outputDerived1->GetValueByName( r, "Standard Deviation" ).ToDouble() - stdevs1[r] ) > 1.e-5 )
|
|
{
|
|
vtkGenericWarningMacro("Incorrect standard deviation");
|
|
testStatus = 1;
|
|
}
|
|
cout << "\n";
|
|
}
|
|
|
|
// Check some results of the Test option
|
|
cout << "\n## Calculated the following Jarque-Bera statistics:\n";
|
|
for ( vtkIdType r = 0; r < outputTest1->GetNumberOfRows(); ++ r )
|
|
{
|
|
cout << " ";
|
|
for ( int i = 0; i < outputTest1->GetNumberOfColumns(); ++ i )
|
|
{
|
|
cout << outputTest1->GetColumnName( i )
|
|
<< "="
|
|
<< outputTest1->GetValue( r, i ).ToString()
|
|
<< " ";
|
|
}
|
|
|
|
cout << "\n";
|
|
}
|
|
|
|
// Search for outliers to check results of Assess option
|
|
double maxdev = 1.5;
|
|
cout << "\n## Searching for outliers from mean with relative deviation > "
|
|
<< maxdev
|
|
<< " for metric 1:\n";
|
|
|
|
vtkDoubleArray* vals0 = vtkDoubleArray::SafeDownCast( outputData1->GetColumnByName( "Metric 0" ) );
|
|
vtkDoubleArray* vals1 = vtkDoubleArray::SafeDownCast( outputData1->GetColumnByName( "Metric 1" ) );
|
|
vtkDoubleArray* devs0 = vtkDoubleArray::SafeDownCast( outputData1->GetColumnByName( "d(Metric 0)" ) );
|
|
vtkDoubleArray* devs1 = vtkDoubleArray::SafeDownCast( outputData1->GetColumnByName( "d(Metric 1)" ) );
|
|
|
|
if ( ! devs0 || ! devs1 || ! vals0 || ! vals1 )
|
|
{
|
|
vtkGenericWarningMacro("Empty output column(s).\n");
|
|
testStatus = 1;
|
|
|
|
return testStatus;
|
|
}
|
|
|
|
double dev;
|
|
int m0outliers = 0;
|
|
int m1outliers = 0;
|
|
for ( vtkIdType r = 0; r < outputData1->GetNumberOfRows(); ++ r )
|
|
{
|
|
dev = devs0->GetValue( r );
|
|
if ( dev > maxdev )
|
|
{
|
|
++ m0outliers;
|
|
cout << " "
|
|
<< " row "
|
|
<< r
|
|
<< ", "
|
|
<< devs0->GetName()
|
|
<< " = "
|
|
<< dev
|
|
<< " > "
|
|
<< maxdev
|
|
<< " (value: "
|
|
<< vals0->GetValue( r )
|
|
<< ")\n";
|
|
}
|
|
}
|
|
for ( vtkIdType r = 0; r < outputData1->GetNumberOfRows(); ++ r )
|
|
{
|
|
dev = devs1->GetValue( r );
|
|
if ( dev > maxdev )
|
|
{
|
|
++ m1outliers;
|
|
cout << " "
|
|
<< " row "
|
|
<< r
|
|
<< ", "
|
|
<< devs1->GetName()
|
|
<< " = "
|
|
<< dev
|
|
<< " > "
|
|
<< maxdev
|
|
<< " (value: "
|
|
<< vals1->GetValue( r )
|
|
<< ")\n";
|
|
}
|
|
}
|
|
|
|
cout << " Found "
|
|
<< m0outliers
|
|
<< " outliers for Metric 0"
|
|
<< " and "
|
|
<< m1outliers
|
|
<< " outliers for Metric 1.\n";
|
|
|
|
if ( m0outliers != 4 || m1outliers != 6 )
|
|
{
|
|
vtkGenericWarningMacro("Expected 4 outliers for Metric 0 and 6 outliers for Metric 1.");
|
|
testStatus = 1;
|
|
}
|
|
|
|
// Now, used modified output 1 as input 1 to test 0-deviation
|
|
cout << "\n## Searching for values not equal to 50 for metric 1:\n";
|
|
|
|
vtkTable* modifiedPrimary = vtkTable::New();
|
|
modifiedPrimary->ShallowCopy( outputPrimary1 );
|
|
modifiedPrimary->SetValueByName( 1, "Mean", 50. );
|
|
|
|
vtkTable* modifiedDerived = vtkTable::New();
|
|
modifiedDerived->ShallowCopy( outputDerived1 );
|
|
modifiedDerived->SetValueByName( 1, "Standard Deviation", 0. );
|
|
|
|
vtkMultiBlockDataSet* modifiedModel = vtkMultiBlockDataSet::New();
|
|
modifiedModel->SetNumberOfBlocks( 2 );
|
|
modifiedModel->SetBlock( 0, modifiedPrimary );
|
|
modifiedModel->SetBlock( 1, modifiedDerived );
|
|
|
|
// Run with Assess option only (do not recalculate nor rederive a model)
|
|
ds1->SetInput( vtkStatisticsAlgorithm::INPUT_MODEL, modifiedModel );
|
|
ds1->SetLearnOption( false );
|
|
ds1->SetDeriveOption( false );
|
|
ds1->SetTestOption( true );
|
|
ds1->SetAssessOption( true );
|
|
ds1->Update();
|
|
|
|
vals1 = vtkDoubleArray::SafeDownCast( outputData1->GetColumnByName( "Metric 1" ) );
|
|
devs1 = vtkDoubleArray::SafeDownCast( outputData1->GetColumnByName( "d(Metric 1)" ) );
|
|
|
|
if ( ! devs1 || ! vals1 )
|
|
{
|
|
vtkGenericWarningMacro("Empty output column(s).\n");
|
|
testStatus = 1;
|
|
|
|
return testStatus;
|
|
}
|
|
|
|
m1outliers = 0;
|
|
for ( vtkIdType r = 0; r < outputData1->GetNumberOfRows(); ++ r )
|
|
{
|
|
dev = devs1->GetValue( r );
|
|
if ( dev )
|
|
{
|
|
++ m1outliers;
|
|
}
|
|
}
|
|
|
|
cout << " Found "
|
|
<< m1outliers
|
|
<< " outliers for Metric 1.\n";
|
|
|
|
if ( m1outliers != 28 )
|
|
{
|
|
vtkGenericWarningMacro("Expected 28 outliers for Metric 1, found " << m1outliers << ".");
|
|
testStatus = 1;
|
|
}
|
|
|
|
// Clean up (which implies resetting input model to first algorithm parameters table values which were modified to their initial values)
|
|
modifiedPrimary->SetValueByName( 1, "Mean", means1[1] );
|
|
modifiedPrimary->Delete();
|
|
modifiedDerived->SetValueByName( 1, "Standard Deviation", stdevs1[1] );
|
|
modifiedDerived->Delete();
|
|
modifiedModel->Delete();
|
|
|
|
// Test with a slight variation of initial data set (to test model aggregation)
|
|
int nVals2 = 32;
|
|
|
|
vtkDoubleArray* dataset4Arr = vtkDoubleArray::New();
|
|
dataset4Arr->SetNumberOfComponents( 1 );
|
|
dataset4Arr->SetName( "Metric 0" );
|
|
|
|
vtkDoubleArray* dataset5Arr = vtkDoubleArray::New();
|
|
dataset5Arr->SetNumberOfComponents( 1 );
|
|
dataset5Arr->SetName( "Metric 1" );
|
|
|
|
vtkDoubleArray* dataset6Arr = vtkDoubleArray::New();
|
|
dataset6Arr->SetNumberOfComponents( 1 );
|
|
dataset6Arr->SetName( "Metric 2" );
|
|
|
|
for ( int i = 0; i < nVals2; ++ i )
|
|
{
|
|
int ti = i << 1;
|
|
dataset4Arr->InsertNextValue( mingledData[ti] + 1. );
|
|
dataset5Arr->InsertNextValue( mingledData[ti + 1] );
|
|
dataset6Arr->InsertNextValue( 1. );
|
|
}
|
|
|
|
vtkTable* datasetTable2 = vtkTable::New();
|
|
datasetTable2->AddColumn( dataset4Arr );
|
|
dataset4Arr->Delete();
|
|
datasetTable2->AddColumn( dataset5Arr );
|
|
dataset5Arr->Delete();
|
|
datasetTable2->AddColumn( dataset6Arr );
|
|
dataset6Arr->Delete();
|
|
|
|
// Set descriptive statistics algorithm and its input data port
|
|
vtkDescriptiveStatistics* ds2 = vtkDescriptiveStatistics::New();
|
|
ds2->SetInput( vtkStatisticsAlgorithm::INPUT_DATA, datasetTable2 );
|
|
|
|
// Select Columns of Interest (all of them)
|
|
for ( int i = 0; i< nMetrics; ++ i )
|
|
{
|
|
ds2->AddColumn( columns[i] );
|
|
}
|
|
|
|
// Update with Learn option only
|
|
ds2->SetLearnOption( true );
|
|
ds2->SetDeriveOption( false );
|
|
ds2->SetTestOption( false );
|
|
ds2->SetAssessOption( false );
|
|
ds2->Update();
|
|
|
|
// Get output meta tables
|
|
vtkMultiBlockDataSet* outputMetaDS2 = vtkMultiBlockDataSet::SafeDownCast( ds2->GetOutputDataObject( vtkStatisticsAlgorithm::OUTPUT_MODEL ) );
|
|
vtkTable* outputPrimary2 = vtkTable::SafeDownCast( outputMetaDS2->GetBlock( 0 ) );
|
|
|
|
cout << "\n## Calculated the following primary statistics for second data set:\n";
|
|
for ( vtkIdType r = 0; r < outputPrimary2->GetNumberOfRows(); ++ r )
|
|
{
|
|
cout << " ";
|
|
for ( int i = 0; i < outputPrimary2->GetNumberOfColumns(); ++ i )
|
|
{
|
|
cout << outputPrimary2->GetColumnName( i )
|
|
<< "="
|
|
<< outputPrimary2->GetValue( r, i ).ToString()
|
|
<< " ";
|
|
}
|
|
cout << "\n";
|
|
}
|
|
|
|
// Clean up
|
|
ds2->Delete();
|
|
|
|
// Test model aggregation by adding new data to engine which already has a model
|
|
ds1->SetInput( vtkStatisticsAlgorithm::INPUT_DATA, datasetTable2 );
|
|
datasetTable2->Delete();
|
|
vtkMultiBlockDataSet* model = vtkMultiBlockDataSet::New();
|
|
model->ShallowCopy( outputMetaDS1 );
|
|
ds1->SetInput( vtkStatisticsAlgorithm::INPUT_MODEL, model );
|
|
model->Delete();
|
|
|
|
// Update with Learn and Derive options only
|
|
ds1->SetLearnOption( true );
|
|
ds1->SetDeriveOption( true );
|
|
ds1->SetTestOption( false );
|
|
ds1->SetAssessOption( false );
|
|
ds1->Update();
|
|
|
|
// Updated reference values
|
|
// Means deviations for metrics 0, 1, and 2, respectively
|
|
double means0[] = { 49.71875 , 49.5, 0. };
|
|
|
|
// Standard deviations for metrics 0, 1, and 2, respectively
|
|
double stdevs0[] = { sqrt( 6.1418651 ), sqrt( 7.548397 * 62. / 63. ), sqrt( 64. / 63. ) };
|
|
|
|
// Get output data and meta tables
|
|
outputMetaDS1 = vtkMultiBlockDataSet::SafeDownCast( ds1->GetOutputDataObject( vtkStatisticsAlgorithm::OUTPUT_MODEL ) );
|
|
outputPrimary1 = vtkTable::SafeDownCast( outputMetaDS1->GetBlock( 0 ) );
|
|
outputDerived1 = vtkTable::SafeDownCast( outputMetaDS1->GetBlock( 1 ) );
|
|
|
|
cout << "\n## Calculated the following primary statistics for updated (first + second) data set:\n";
|
|
for ( vtkIdType r = 0; r < outputPrimary1->GetNumberOfRows(); ++ r )
|
|
{
|
|
cout << " ";
|
|
for ( int i = 0; i < outputPrimary1->GetNumberOfColumns(); ++ i )
|
|
{
|
|
cout << outputPrimary1->GetColumnName( i )
|
|
<< "="
|
|
<< outputPrimary1->GetValue( r, i ).ToString()
|
|
<< " ";
|
|
}
|
|
|
|
// Verify some of the calculated primary statistics
|
|
if ( fabs ( outputPrimary1->GetValueByName( r, "Mean" ).ToDouble() - means0[r] ) > 1.e-6 )
|
|
{
|
|
vtkGenericWarningMacro("Incorrect mean");
|
|
testStatus = 1;
|
|
}
|
|
cout << "\n";
|
|
}
|
|
|
|
cout << "\n## Calculated the following derived statistics for updated (first + second) data set:\n";
|
|
for ( vtkIdType r = 0; r < outputDerived1->GetNumberOfRows(); ++ r )
|
|
{
|
|
cout << " ";
|
|
for ( int i = 0; i < outputDerived1->GetNumberOfColumns(); ++ i )
|
|
{
|
|
cout << outputDerived1->GetColumnName( i )
|
|
<< "="
|
|
<< outputDerived1->GetValue( r, i ).ToString()
|
|
<< " ";
|
|
}
|
|
|
|
// Verify some of the calculated derived statistics
|
|
if ( fabs ( outputDerived1->GetValueByName( r, "Standard Deviation" ).ToDouble() - stdevs0[r] ) > 1.e-5 )
|
|
{
|
|
vtkGenericWarningMacro("Incorrect standard deviation");
|
|
testStatus = 1;
|
|
}
|
|
cout << "\n";
|
|
}
|
|
|
|
// Clean up
|
|
ds1->Delete();
|
|
|
|
// ************** Very simple example, for baseline comparison vs. R *********
|
|
double simpleData[] =
|
|
{
|
|
0,
|
|
1,
|
|
2,
|
|
3,
|
|
4,
|
|
5,
|
|
6,
|
|
7,
|
|
8,
|
|
9,
|
|
};
|
|
int nSimpleVals = 10;
|
|
|
|
vtkDoubleArray* datasetArr = vtkDoubleArray::New();
|
|
datasetArr->SetNumberOfComponents( 1 );
|
|
datasetArr->SetName( "Digits" );
|
|
|
|
for ( int i = 0; i < nSimpleVals; ++ i )
|
|
{
|
|
datasetArr->InsertNextValue( simpleData[i] );
|
|
}
|
|
|
|
vtkTable* simpleTable = vtkTable::New();
|
|
simpleTable->AddColumn( datasetArr );
|
|
datasetArr->Delete();
|
|
|
|
double mean = 4.5;
|
|
double variance = 9.16666666666667;
|
|
double skewness = 0.;
|
|
double kurtosis = -1.56163636363636;
|
|
|
|
// Set descriptive statistics algorithm and its input data port
|
|
vtkDescriptiveStatistics* ds3 = vtkDescriptiveStatistics::New();
|
|
ds3->SetInput( vtkStatisticsAlgorithm::INPUT_DATA, simpleTable );
|
|
simpleTable->Delete();
|
|
|
|
// Select column of interest
|
|
ds3->AddColumn( "Digits" );
|
|
|
|
// Add non existing column
|
|
ds3->AddColumn( "Bogus" );
|
|
|
|
// Warning for non existing column will mess up output
|
|
cout << "\n";
|
|
|
|
// Test Learn and Derive options only
|
|
ds3->SetLearnOption( true );
|
|
ds3->SetDeriveOption( true );
|
|
ds3->SetTestOption( false );
|
|
ds3->SetAssessOption( false );
|
|
ds3->Update();
|
|
|
|
// Get output data and meta tables
|
|
vtkMultiBlockDataSet* outputMetaDS3 = vtkMultiBlockDataSet::SafeDownCast( ds3->GetOutputDataObject( vtkStatisticsAlgorithm::OUTPUT_MODEL ) );
|
|
vtkTable* outputPrimary3 = vtkTable::SafeDownCast( outputMetaDS3->GetBlock( 0 ) );
|
|
vtkTable* outputDerived3 = vtkTable::SafeDownCast( outputMetaDS3->GetBlock( 1 ) );
|
|
|
|
cout << "\n## Calculated the following primary statistics for {0,...9} sequence:\n";
|
|
cout << " ";
|
|
for ( int i = 0; i < outputPrimary3->GetNumberOfColumns(); ++ i )
|
|
{
|
|
cout << outputPrimary3->GetColumnName( i )
|
|
<< "="
|
|
<< outputPrimary3->GetValue( 0, i ).ToString()
|
|
<< " ";
|
|
}
|
|
|
|
// Verify some of the calculated primary statistics
|
|
if ( fabs ( outputPrimary3->GetValueByName( 0, "Mean" ).ToDouble() - mean ) > 1.e-6 )
|
|
{
|
|
vtkGenericWarningMacro("Incorrect mean");
|
|
testStatus = 1;
|
|
}
|
|
cout << "\n";
|
|
|
|
cout << "\n## Calculated the following derived statistics for {0,...9} sequence:\n";
|
|
cout << " ";
|
|
for ( int i = 0; i < outputDerived3->GetNumberOfColumns(); ++ i )
|
|
{
|
|
cout << outputDerived3->GetColumnName( i )
|
|
<< "="
|
|
<< outputDerived3->GetValue( 0, i ).ToString()
|
|
<< " ";
|
|
}
|
|
|
|
// Verify some of the calculated derived statistics
|
|
if ( fabs ( outputDerived3->GetValueByName( 0, "Variance" ).ToDouble() - variance ) > 1.e-6 )
|
|
{
|
|
vtkGenericWarningMacro("Incorrect variance");
|
|
testStatus = 1;
|
|
}
|
|
|
|
if ( fabs ( outputDerived3->GetValueByName( 0, "Skewness" ).ToDouble() - skewness ) > 1.e-6 )
|
|
{
|
|
vtkGenericWarningMacro("Incorrect skewness");
|
|
testStatus = 1;
|
|
}
|
|
|
|
if ( fabs ( outputDerived3->GetValueByName( 0, "Kurtosis" ).ToDouble() - kurtosis ) > 1.e-6 )
|
|
{
|
|
vtkGenericWarningMacro("Incorrect kurtosis");
|
|
testStatus = 1;
|
|
}
|
|
cout << "\n";
|
|
|
|
// Clean up
|
|
ds3->Delete();
|
|
|
|
// ************** Pseudo-random sample to exercise Jarque-Bera test *********
|
|
int nVals = 10000;
|
|
|
|
vtkDoubleArray* datasetNormal = vtkDoubleArray::New();
|
|
datasetNormal->SetNumberOfComponents( 1 );
|
|
datasetNormal->SetName( "Standard Normal" );
|
|
|
|
vtkDoubleArray* datasetUniform = vtkDoubleArray::New();
|
|
datasetUniform->SetNumberOfComponents( 1 );
|
|
datasetUniform->SetName( "Standard Uniform" );
|
|
|
|
vtkDoubleArray* datasetLogNormal = vtkDoubleArray::New();
|
|
datasetLogNormal->SetNumberOfComponents( 1 );
|
|
datasetLogNormal->SetName( "Standard Log-Normal" );
|
|
|
|
vtkDoubleArray* datasetExponential = vtkDoubleArray::New();
|
|
datasetExponential->SetNumberOfComponents( 1 );
|
|
datasetExponential->SetName( "Standard Exponential" );
|
|
|
|
vtkDoubleArray* datasetLaplace = vtkDoubleArray::New();
|
|
datasetLaplace->SetNumberOfComponents( 1 );
|
|
datasetLaplace->SetName( "Standard Laplace" );
|
|
|
|
// Seed random number generator
|
|
vtkMath::RandomSeed( static_cast<int>( vtkTimerLog::GetUniversalTime() ) );
|
|
|
|
for ( int i = 0; i < nVals; ++ i )
|
|
{
|
|
datasetNormal->InsertNextValue( vtkMath::Gaussian() );
|
|
datasetUniform->InsertNextValue( vtkMath::Random() );
|
|
datasetLogNormal->InsertNextValue( exp( vtkMath::Gaussian() ) );
|
|
datasetExponential->InsertNextValue( -log ( vtkMath::Random() ) );
|
|
double u = vtkMath::Random() - .5;
|
|
datasetLaplace->InsertNextValue( ( u < 0. ? 1. : -1. ) * log ( 1. - 2. * fabs( u ) ) );
|
|
}
|
|
|
|
vtkTable* gaussianTable = vtkTable::New();
|
|
gaussianTable->AddColumn( datasetNormal );
|
|
datasetNormal->Delete();
|
|
gaussianTable->AddColumn( datasetUniform );
|
|
datasetUniform->Delete();
|
|
gaussianTable->AddColumn( datasetLogNormal );
|
|
datasetLogNormal->Delete();
|
|
gaussianTable->AddColumn( datasetExponential );
|
|
datasetExponential->Delete();
|
|
gaussianTable->AddColumn( datasetLaplace );
|
|
datasetLaplace->Delete();
|
|
|
|
// Set descriptive statistics algorithm and its input data port
|
|
vtkDescriptiveStatistics* ds4 = vtkDescriptiveStatistics::New();
|
|
ds4->SetInput( vtkStatisticsAlgorithm::INPUT_DATA, gaussianTable );
|
|
gaussianTable->Delete();
|
|
|
|
// Select Column of Interest
|
|
ds4->AddColumn( "Standard Normal" );
|
|
ds4->AddColumn( "Standard Uniform" );
|
|
ds4->AddColumn( "Standard Log-Normal" );
|
|
ds4->AddColumn( "Standard Exponential" );
|
|
ds4->AddColumn( "Standard Laplace" );
|
|
|
|
// Test Learn, Derive, and Test options only
|
|
ds4->SetLearnOption( true );
|
|
ds4->SetDeriveOption( true );
|
|
ds4->SetTestOption( true );
|
|
ds4->SetAssessOption( false );
|
|
ds4->Update();
|
|
|
|
// Get output data and meta tables
|
|
vtkMultiBlockDataSet* outputMetaDS4 = vtkMultiBlockDataSet::SafeDownCast( ds4->GetOutputDataObject( vtkStatisticsAlgorithm::OUTPUT_MODEL ) );
|
|
vtkTable* outputPrimary4 = vtkTable::SafeDownCast( outputMetaDS4->GetBlock( 0 ) );
|
|
vtkTable* outputDerived4 = vtkTable::SafeDownCast( outputMetaDS4->GetBlock( 1 ) );
|
|
vtkTable* outputTest4 = ds4->GetOutput( vtkStatisticsAlgorithm::OUTPUT_TEST );
|
|
|
|
cout << "\n## Calculated the following primary statistics for pseudo-random variables (n="
|
|
<< nVals
|
|
<< "):\n";
|
|
for ( vtkIdType r = 0; r < outputPrimary4->GetNumberOfRows(); ++ r )
|
|
{
|
|
cout << " ";
|
|
for ( int i = 0; i < outputPrimary4->GetNumberOfColumns(); ++ i )
|
|
{
|
|
cout << outputPrimary4->GetColumnName( i )
|
|
<< "="
|
|
<< outputPrimary4->GetValue( r, i ).ToString()
|
|
<< " ";
|
|
}
|
|
|
|
cout << "\n";
|
|
}
|
|
|
|
cout << "\n## Calculated the following derived statistics for pseudo-random variables (n="
|
|
<< nVals
|
|
<< "):\n";
|
|
for ( vtkIdType r = 0; r < outputDerived4->GetNumberOfRows(); ++ r )
|
|
{
|
|
cout << " ";
|
|
for ( int i = 0; i < outputDerived4->GetNumberOfColumns(); ++ i )
|
|
{
|
|
cout << outputDerived4->GetColumnName( i )
|
|
<< "="
|
|
<< outputDerived4->GetValue( r, i ).ToString()
|
|
<< " ";
|
|
}
|
|
|
|
cout << "\n";
|
|
}
|
|
|
|
// Check some results of the Test option
|
|
cout << "\n## Calculated the following Jarque-Bera statistics for pseudo-random variables (n="
|
|
<< nVals;
|
|
|
|
#ifdef VTK_USE_GNU_R
|
|
int nNonGaussian = 3;
|
|
int nRejected = 0;
|
|
double alpha = .01;
|
|
|
|
cout << ", null hypothesis: normality, significance level="
|
|
<< alpha;
|
|
#endif // VTK_USE_GNU_R
|
|
|
|
cout << "):\n";
|
|
|
|
// Loop over Test table
|
|
for ( vtkIdType r = 0; r < outputTest4->GetNumberOfRows(); ++ r )
|
|
{
|
|
cout << " ";
|
|
for ( int c = 0; c < outputTest4->GetNumberOfColumns(); ++ c )
|
|
{
|
|
cout << outputTest4->GetColumnName( c )
|
|
<< "="
|
|
<< outputTest4->GetValue( r, c ).ToString()
|
|
<< " ";
|
|
}
|
|
|
|
#ifdef VTK_USE_GNU_R
|
|
// Check if null hypothesis is rejected at specified significance level
|
|
double p = outputTest4->GetValueByName( r, "P" ).ToDouble();
|
|
// Must verify that p value is valid (it is set to -1 if R has failed)
|
|
if ( p > -1 && p < alpha )
|
|
{
|
|
cout << "N.H. rejected";
|
|
|
|
++ nRejected;
|
|
}
|
|
#endif // VTK_USE_GNU_R
|
|
|
|
cout << "\n";
|
|
}
|
|
|
|
#ifdef VTK_USE_GNU_R
|
|
if ( nRejected < nNonGaussian )
|
|
{
|
|
vtkGenericWarningMacro("Rejected only "
|
|
<< nRejected
|
|
<< " null hypotheses of normality whereas "
|
|
<< nNonGaussian
|
|
<< " variables are not Gaussian");
|
|
testStatus = 1;
|
|
}
|
|
#endif // VTK_USE_GNU_R
|
|
|
|
// Clean up
|
|
ds4->Delete();
|
|
|
|
return testStatus;
|
|
}
|