[vtkusers] K-means values

David Thompson dcthomp at sandia.gov
Mon Mar 21 13:14:03 EDT 2011


Hi Sara,

> ... I had also tried GetOutputDataObject( 1 )->GetBlock( 0 ),  
> replacing
> the dot with an arrow, but this just resulted in a different error:
>
> error: ‘class vtkDataObject’ has no member named ‘GetBlock’

Ah. The filter output is actually a vtkMultiBlockDataset which  
inherits vtkDataObject. The subclass provides GetBlock but  
vtkDataObject does not. Therefore the output of  
GetOutputDataObject( 1 ) must be cast to a multiblock dataset:

   vtkMultiBlockDataSet::SafeDownCast( kMeansStatistics- 
 >GetOutputDataObject( 1 ) )->GetBlock( 0 )

should return another vtkDataObject pointer which you must cast to  
vtkTable in order to access the results.

     David


>
> On Mar 18, 2011, at 6:52 PM, David Thompson wrote:
>
>> Hi Sara,
>>
>>> Update: from the vtkKMeansStatistics reference page it sounds like
>>> it's necessary for the first column to be a vtkIdType array in
>>> order for learning to be used and the table available on the output
>>> port.
>>
>> Only the first column of a table on the LEARN_PARAMETERS port needs
>> to be vtkIdTypeArray. In the code below, the inputData table is
>> attached to the INPUT_DATA port, so there's no constraint on the
>> column type. I'm not sure I understand exactly what the code is
>> supposed to accomplish; the column you create named "KMeans" is
>> initially going to be filled with zeros. The other column will be
>> named FeatureInArrayName (not "ScalarMagnitude" because your don't
>> ever call inputData->AddColumn on floatArray). Since all the values
>> in the first column are identical and both Learn and Assess are
>> turned on, the filter will
>> 1. Perform Learn by randomly choosing "clusterCount" cluster centers
>> (since no LEARN_PARAMETERS input was set) and computing a single
>> iteration of k-means.
>> 2. Perform Assess by adding 2 columns to the input table: one
>> vtkDoubleArray containing the squared distance to the nearest
>> cluster center, and one vtkIdTypeArray containing the nearest
>> cluster center's ID (as reported by the OUTPUT_MODEL output).
>> The output model kMeansStatistics->GetOutputDataObject(1)-
>>> GetBlock(0) will report all of the cluster centers as lying on the
>> line "KMeans"=0.
>> Is that what you had in mind?
>>
>> 	David
>>
>>> 	//get data from the file
>>> 	vtkXMLPolyDataReader* reader = vtkXMLPolyDataReader::New();
>>> 	reader->SetFileName( inputFile );
>>> 	reader->Update();
>>> 	vtkPolyData* polydata = reader->GetOutput();
>>> 	cout << "Reading data" << endl;
>>> 	
>>> 	vtkSmartPointer<vtkFloatArray> magnitudeArray =
>>> vtkFloatArray::SafeDownCast(polydata->GetPointData()-
>>>> GetArray(FeatureInArrayName));
>>> 	
>>> 	// set up table for KMeans
>>> 	vtkSmartPointer<vtkTable> inputData =
>>> vtkSmartPointer<vtkTable>::New();
>>> 	
>>> 	// first column for kmeans clusters, vtkIdType
>>> 	vtkSmartPointer<vtkIdTypeArray> idArray =
>>> vtkSmartPointer<vtkIdTypeArray>::New();
>>>   	idArray->SetNumberOfComponents(1);
>>>  	idArray->SetName( "KMeans" );
>>>   	idArray->SetNumberOfTuples(polydata->GetNumberOfPoints());
>>> 	inputData->AddColumn( idArray );
>>> 	
>>> 	// second column for data values
>>> 	vtkSmartPointer<vtkFloatArray> floatArray =
>>> vtkSmartPointer<vtkFloatArray>::New();
>>> 	floatArray->SetNumberOfComponents(1);
>>> 	floatArray->SetName( "ScalerMagnitude" );
>>> 	floatArray->SetNumberOfTuples(polydata->GetNumberOfPoints());
>>> 	inputData->AddColumn( magnitudeArray );
>>> 	
>>> 	// KMeans Set up
>>> 	vtkSmartPointer<vtkKMeansStatistics> kMeansStatistics =
>>> vtkSmartPointer<vtkKMeansStatistics>::New();
>>> 	
>>> 	kMeansStatistics->SetInput( vtkStatisticsAlgorithm::INPUT_DATA,
>>> inputData );
>>> 	kMeansStatistics->SetColumnStatus( inputData->GetColumnName( 0 ) ,
>>> 1 );
>>> 	kMeansStatistics->SetColumnStatus( inputData->GetColumnName( 1 ) ,
>>> 1 );
>>> 	kMeansStatistics->RequestSelectedColumns();
>>> 	kMeansStatistics->SetDefaultNumberOfClusters( clusterCount );
>>> 	kMeansStatistics->SetAssessOption( 1 );	
>>> 	kMeansStatistics->SetLearnOption( 1 );
>>> 	kMeansStatistics->SetMaxNumIterations( 1 );
>>> 	kMeansStatistics->Update() ;
>>> 	
>>> 	//vtkTable* tab = vtkTable::SafeDownCast( kMeansStatistics-
>>>> GetOutputDataObject( 1 ).GetBlock( 0 ) );
>>> 	//double xc = tab->GetValueByName( label, "x" ).ToDouble();
>>> 	kMeansStatistics->GetOutputDataObject(1).GetBlock( 0 );
>>>
>>>
>>> On Mar 18, 2011, at 4:30 PM, Sara Rolfe wrote:
>>>
>>>> I agree.  I also think that the example on the  wiki might be more
>>>> helpful if it showed this method of accessing the means.
>>>>
>>>> However, I'm still having some trouble accessing the first block
>>>> of the k-means output, when I use:
>>>>
>>>> 	vtkTable* tab = vtkTable::SafeDownCast( kMeansStatistics-
>>>>> GetOutputDataObject( 1 ).GetBlock( 0 ) );
>>>>
>>>> or just
>>>> 	kMeansStatistics->GetOutputDataObject( 1 ).GetBlock( 0 )
>>>>
>>>> I'm getting the following error:
>>>>
>>>> error: request for member ‘GetBlock’ in ‘kMeansStatistics.
>>>> vtkSmartPointer<T>::operator-> [with T = vtkKMeansStatistics]()-
>>>>>
>>>> vtkKMeansStatistics
>>>> ::<
>>>> anonymous
>>>>>
>>>> .vtkStatisticsAlgorithm
>>>> ::<
>>>> anonymous
>>>>>
>>>> .vtkTableAlgorithm
>>>> ::<anonymous>.vtkAlgorithm::GetOutputDataObject(1)’, which is of
>>>> non-class type ‘vtkDataObject*’
>>>>
>>>> Does anyone know what might cause this?
>>>>
>>>> Thanks,
>>>> Sara
>>>>
>>>> On Mar 16, 2011, at 5:32 PM, David Doria wrote:
>>>>
>>>>> On Wed, Mar 16, 2011 at 4:07 PM, Sara Rolfe <smrolfe at u.washington.edu
>>>>>> wrote:
>>>>>>
>>>>>> Hi David,
>>>>>>
>>>>>> It's not a difficult fix, I mainly found it awkward since I
>>>>>> thought I was missing something simple.  I understand how it
>>>>>> works better now and can certainly implement it this way.  I
>>>>>> appreciate your clarification.
>>>>>>
>>>>>> Sara
>>>>>
>>>>> If you recall, I had the same sort of "it feels awkward" issues a
>>>>> while back. I think the problem is that the suite is very very
>>>>> capable
>>>>> and able to hand very large and serious problems, but many users
>>>>> just
>>>>> want the "very basic" functionality ("which points belong to which
>>>>> cluster?", and "what are the cluster means?"), which is hard to  
>>>>> get
>>>>> at. There are many layers of complexity above that that a user  
>>>>> must
>>>>> understand (i.e. this "Learn" and "Derive" that you mentioned)  
>>>>> that
>>>>> are not concepts in a standard textbook explanation of kmeans
>>>>> clustering. Providing a "simple" interface to do this "one pass"
>>>>> type
>>>>> of thing would definitely be a nice addition.
>>>>>
>>>>> That is, replace:
>>>>>
>>>>> kMeansStatistics->SetLearnOption( 1 ); // This is on by default.
>>>>> kMeansStatistics->SetMaxNumIterations( 1 );
>>>>> vtkTable* tab = vtkTable::SafeDownCast(
>>>>> kMeansStatistics->GetOutputDataObject( 1 ).GetBlock( 0 ) );
>>>>> double xc = tab->GetValueByName( label, "x" ).ToDouble();
>>>>>
>>>>> with
>>>>>
>>>>> double mean0[3];
>>>>> kMeans->GetMean(0,mean0);
>>>>>
>>>>> See the difference :) ?
>>>>>
>>>>> David D.
>>>>
>>>> _______________________________________________
>>>> Powered by www.kitware.com
>>>>
>>>> Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html
>>>>
>>>> Please keep messages on-topic and check the VTK FAQ at: http://www.vtk.org/Wiki/VTK_FAQ
>>>>
>>>> Follow this link to subscribe/unsubscribe:
>>>> http://www.vtk.org/mailman/listinfo/vtkusers
>>>
>>
>>
>>
>>
>
>





More information about the vtkusers mailing list