/*
* File: VectorMeanCentroidClusterCreator.java
* Authors: Justin Basilico
* Company: Sandia National Laboratories
* Project: Cognitive Foundry
*
* Copyright March 20, 2006, 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. Export of this program may require a
* license from the United States Government. See CopyrightHistory.txt for
* complete details.
*
*/
package gov.sandia.cognition.learning.algorithm.clustering.cluster;
import gov.sandia.cognition.annotation.CodeReview;
import gov.sandia.cognition.math.matrix.Vector;
import gov.sandia.cognition.util.AbstractCloneableSerializable;
import java.util.ArrayList;
import java.util.Collection;
/**
* The <code>VectorMeanCentroidClusterCreator</code> class implements
* a cluster creator for centroid clusters where the centroid is the
* mean of the vectors that are members of the cluster.
*
* @author Justin Basilico
* @since 1.0
*/
@CodeReview(
reviewer="Kevin R. Dixon",
date="2008-07-22",
changesNeeded=false,
comments="Code generally looks fine."
)
public class VectorMeanCentroidClusterCreator
extends AbstractCloneableSerializable
implements IncrementalClusterCreator<CentroidCluster<Vector>, Vector>
{
/** An instance of this class since it has no internal data. */
public static final VectorMeanCentroidClusterCreator INSTANCE =
new VectorMeanCentroidClusterCreator();
/**
* Creates a new instance of VectorMeanCentroidClusterCreator
*/
public VectorMeanCentroidClusterCreator()
{
super();
}
@Override
public CentroidCluster<Vector> createCluster()
{
return new CentroidCluster<Vector>(null, new ArrayList<Vector>());
}
@Override
public CentroidCluster<Vector> createCluster(
final Collection<? extends Vector> members)
{
if (members.size() <= 0)
{
// No members to create the cluster from.
return new CentroidCluster<Vector>(null, members);
}
// We are going to create the mean centroid of the cluster.
Vector centroid = null;
for (Vector member : members)
{
if (centroid == null)
{
centroid = member.clone();
}
else
{
centroid.plusEquals(member);
}
}
centroid.scaleEquals(1.0 / (double) members.size());
return new CentroidCluster<Vector>(centroid, members);
}
@Override
public void addClusterMember(
final CentroidCluster<Vector> cluster,
final Vector member)
{
Vector centroid = cluster.getCentroid();
if (centroid == null)
{
centroid = member.clone();
cluster.setCentroid(centroid);
}
else
{
final int oldSize = cluster.getMembers().size();
final int newSize = oldSize + 1;
final Vector delta = member.minus(centroid);
delta.scaleEquals(1.0 / newSize);
centroid.plusEquals(delta);
}
cluster.getMembers().add(member);
}
@Override
public boolean removeClusterMember(
final CentroidCluster<Vector> cluster,
final Vector member)
{
if (cluster.getMembers().remove(member))
{
final int newSize = cluster.getMembers().size();
Vector centroid = cluster.getCentroid();
if (newSize <= 0)
{
centroid.zero();
}
else
{
final Vector delta = member.minus(centroid);
delta.scaleEquals(1.0 / newSize);
centroid.minusEquals(delta);
}
return true;
}
else
{
return false;
}
}
}