1 #include "vtkKMeansDistanceFunctorCalculator.h"
2
3 #include "vtkObjectFactory.h"
4 #include "vtkDoubleArray.h"
5 #include "vtkFunctionParser.h"
6 #include "vtkTable.h"
7 #include "vtkVariantArray.h"
8 #include "vtkIntArray.h"
9 #include "vtkIdTypeArray.h"
10
11 #include <sstream>
12
13 vtkStandardNewMacro(vtkKMeansDistanceFunctorCalculator);
14 vtkCxxSetObjectMacro(vtkKMeansDistanceFunctorCalculator,FunctionParser,vtkFunctionParser);
15
16 // ----------------------------------------------------------------------
vtkKMeansDistanceFunctorCalculator()17 vtkKMeansDistanceFunctorCalculator::vtkKMeansDistanceFunctorCalculator()
18 {
19 this->FunctionParser = vtkFunctionParser::New();
20 this->DistanceExpression = nullptr;
21 this->TupleSize = -1;
22 }
23
24 // ----------------------------------------------------------------------
~vtkKMeansDistanceFunctorCalculator()25 vtkKMeansDistanceFunctorCalculator::~vtkKMeansDistanceFunctorCalculator()
26 {
27 this->SetFunctionParser( nullptr );
28 this->SetDistanceExpression( nullptr );
29 }
30
31 // ----------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)32 void vtkKMeansDistanceFunctorCalculator::PrintSelf( ostream& os, vtkIndent indent )
33 {
34 this->Superclass::PrintSelf( os, indent );
35 os << indent << "FunctionParser: " << this->FunctionParser << "\n";
36 os << indent << "DistanceExpression: "
37 << ( this->DistanceExpression && this->DistanceExpression[0] ? this->DistanceExpression : "nullptr" )
38 << "\n";
39 os << indent << "TupleSize: " << this->TupleSize << "\n";
40 }
41
42 // ----------------------------------------------------------------------
operator ()(double & distance,vtkVariantArray * clusterCoord,vtkVariantArray * dataCoord)43 void vtkKMeansDistanceFunctorCalculator::operator() (
44 double& distance, vtkVariantArray* clusterCoord, vtkVariantArray* dataCoord )
45 {
46 distance = 0.0;
47 vtkIdType nv = clusterCoord->GetNumberOfValues();
48 if ( nv != dataCoord->GetNumberOfValues() )
49 {
50 cout << "The dimensions of the cluster and data do not match." << endl;
51 distance = -1;
52 return;
53 }
54
55 if ( ! this->DistanceExpression )
56 {
57 distance = -1;
58 return;
59 }
60
61 this->FunctionParser->SetFunction( this->DistanceExpression );
62 if ( this->TupleSize != nv )
63 { // Need to update the scalar variable names as well as values...
64 this->FunctionParser->RemoveScalarVariables();
65 for ( vtkIdType i = 0; i < nv; ++ i )
66 {
67 std::ostringstream xos;
68 std::ostringstream yos;
69 xos << "x" << i;
70 yos << "y" << i;
71 this->FunctionParser->SetScalarVariableValue( xos.str().c_str(), clusterCoord->GetValue( i ).ToDouble() );
72 this->FunctionParser->SetScalarVariableValue( yos.str().c_str(), dataCoord->GetValue( i ).ToDouble() );
73 }
74 }
75 else
76 { // Use faster integer comparisons to set values...
77 for ( vtkIdType i = 0; i < nv; ++ i )
78 {
79 this->FunctionParser->SetScalarVariableValue( 2 * i, clusterCoord->GetValue( i ).ToDouble() );
80 this->FunctionParser->SetScalarVariableValue( 2 * i + 1, dataCoord->GetValue( i ).ToDouble() );
81 }
82 }
83 distance = this->FunctionParser->GetScalarResult();
84 /*
85 cout << "f([";
86 for ( vtkIdType i = 0; i < nv; ++ i )
87 cout << " " << dataCoord->GetValue( i ).ToDouble();
88 cout << " ],[";
89 for ( vtkIdType i = 0; i < nv; ++ i )
90 cout << " " << clusterCoord->GetValue( i ).ToDouble();
91 cout << " ]) = " << distance << "\n";
92 */
93 }
94
95