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