All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gov.sandia.cognition.framework.learning.converter.CogxelVectorConverter Maven / Gradle / Ivy

There is a newer version: 4.0.1
Show newest version
/*
 * File:                VectorCogxelMap.java
 * Authors:             Justin Basilico and Kevin R. Dixon
 * Company:             Sandia National Laboratories
 * Project:             Cognitive Framework Lite
 *
 * Copyright June 21, 2007, 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.framework.learning.converter;

import gov.sandia.cognition.collection.CollectionUtil;
import gov.sandia.cognition.framework.Cogxel;
import gov.sandia.cognition.framework.CogxelFactory;
import gov.sandia.cognition.framework.CogxelState;
import gov.sandia.cognition.framework.DefaultCogxelFactory;
import gov.sandia.cognition.framework.SemanticIdentifier;
import gov.sandia.cognition.framework.SemanticIdentifierMap;
import gov.sandia.cognition.framework.SemanticLabel;
import gov.sandia.cognition.math.matrix.DefaultVectorFactoryContainer;
import gov.sandia.cognition.math.matrix.DimensionalityMismatchException;
import gov.sandia.cognition.math.matrix.Vector;
import gov.sandia.cognition.math.matrix.VectorFactory;
import gov.sandia.cognition.math.matrix.VectorFactoryContainer;
import gov.sandia.cognition.util.ObjectUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;

/**
 * The CogxelVectorConverter implements a converter to convert Cogxels to and
 * from Vector objects.
 *
 * @author Justin Basilico
 * @author Kevin R. Dixon
 * @since  1.0
 */
public class CogxelVectorConverter
    extends DefaultVectorFactoryContainer
    implements CogxelConverter
{
    /** The labels for each of the elements in the vector. */
    private ArrayList labels;
    
    /** The current SemanticIdentifierMap. */
    private SemanticIdentifierMap semanticIdentifierMap;
    
    /** The list of SemanticIdentifiers, whose positions correspond to
     *  positions in the vector. */
    private ArrayList identifiers;
    
    /** The mapping of SemanticIdentifiers to vector indices. */
    private HashMap identifierToIndexMap;
    
    /** The CogxelFactory to use. */
    private CogxelFactory cogxelFactory;
    
    /**
     * Creates a new, empty instance of VectorCogxelMap.
     */
    public CogxelVectorConverter()
    {
        super();
        
        this.setLabels(new ArrayList());
        this.setSemanticIdentifierMap(null);
        this.setIdentifiers(new ArrayList());
        this.setIdentifierToIndexMap(new HashMap());
        this.setVectorFactory(VectorFactory.getDefault());
        this.setCogxelFactory(DefaultCogxelFactory.INSTANCE);
    }
    
    /**
     * Creates a new CogxelVectorConverter from the given labels.
     *
     * @param  labels The labels to use.
     */
    public CogxelVectorConverter(
        SemanticLabel... labels)
    {
        this(labels, null);
    }
    
    /**
     * Creates a new CogxelVectorConverter from the given labels.
     *
     * @param  labels The labels to use.
     */
    public CogxelVectorConverter(
        Iterable labels)
    {
        this(labels, null);
    }
    
    /**
     * Creates a new CogxelVectorConverter from the given SemanticIdentifierMap
     * and SemanticLabels.
     *
     * @param  labels The labels to use.
     * @param  semanticIdentifierMap The SemanticIdentifierMap to use.
     */
    public CogxelVectorConverter(
        SemanticLabel[] labels,
        SemanticIdentifierMap semanticIdentifierMap)
    {
        this(Arrays.asList(labels), semanticIdentifierMap);
    }
    
    /**
     * Creates a new CogxelVectorConverter from the given SemanticIdentifierMap
     * and SemanticLabels.
     *
     * @param  labels The labels to use.
     * @param  semanticIdentifierMap The SemanticIdentifierMap to use.
     */
    public CogxelVectorConverter(
        Iterable labels,
        SemanticIdentifierMap semanticIdentifierMap)
    {
        this();
        
        this.addLabels(labels);
        this.setSemanticIdentifierMap(semanticIdentifierMap);
    }
    
    /**
     * Creates a new CogxelVectorConverter
     *
     * @param  labels The labels to use.
     * @param  semanticIdentifierMap The SemanticIdentifierMap to use.
     * @param  vectorFactory The VectorFactory to use.
     * @param  cogxelFactory The CogxelFactory to use.
     */
    public CogxelVectorConverter(
        SemanticLabel[] labels,
        SemanticIdentifierMap semanticIdentifierMap,
        VectorFactory vectorFactory,
        CogxelFactory cogxelFactory)
    {
        this(Arrays.asList(labels), semanticIdentifierMap, vectorFactory, 
            cogxelFactory);
    }
    
    /**
     * Creates a new CogxelVectorConverter.
     *
     * @param  labels The labels to use.
     * @param  semanticIdentifierMap The SemanticIdentifierMap to use.
     * @param  vectorFactory The VectorFactory to use.
     * @param  cogxelFactory The CogxelFactory to use.
     */
    public CogxelVectorConverter(
        Iterable labels,
        SemanticIdentifierMap semanticIdentifierMap,
        VectorFactory vectorFactory,
        CogxelFactory cogxelFactory)
    {
        this(labels, semanticIdentifierMap);
        
        this.setVectorFactory(vectorFactory);
        this.setCogxelFactory(cogxelFactory);
    }
        
    /**
     * Creates a new copy of the given CogxelVectorConverter.
     *
     * @param  other The CogxeLVectorConverter to copy.
     */
    public CogxelVectorConverter(
        CogxelVectorConverter other)
    {
        this(new ArrayList(other.getLabels()),
            other.getSemanticIdentifierMap(), 
            other.getVectorFactory(),
            other.getCogxelFactory());
    }
    
    /**
     * {@inheritDoc}
     *
     * @return {@inheritDoc}
     */
    @Override
    public CogxelVectorConverter clone()
    {
        return new CogxelVectorConverter(this);
    }
    
    /**
     * Adds the given SemanticLabel to the list of labels used by the
     * converter.
     *
     * @param  label The label to add.
     */
    public void addLabel(
        SemanticLabel label)
    {
        // Validate the parameters.
        if ( label == null )
        {
            throw new IllegalArgumentException("label is null");
        }
        
        // Add the label.
        this.getLabels().add(label);
        this.addLabelToIdentifierCache(label);
    }
    
    /**
     * Adds all of the given labels to the converter.
     *
     * @param  labels The labels to add to the converter.
     */
    public void addLabels(
        Iterable labels)
    {
        for ( SemanticLabel label : labels )
        {
            this.addLabel(label);
        }
    }
    
    /**
     * Adds all of the given labels to the converter.
     *
     * @param  labels The labels to add to the converter.
     */
    public void addLabels(
        SemanticLabel[] labels)
    {
        for ( SemanticLabel label : labels )
        {
            this.addLabel(label);
        }
    }
    
    /**
     * Rebuilds the cache of SemanticIdentifier objects. Should only need to
     * be called after the SemanticIdentifierMap is changed.
     */
    protected void buildIdentifierCache()
    {
        // Clear out the semantic identifier containers.
        this.setIdentifiers(
            new ArrayList());
        this.setIdentifierToIndexMap(
            new HashMap());
        
        // Add each label to the cache.
        SemanticIdentifierMap identifierMap = this.getSemanticIdentifierMap();
        if ( identifierMap != null )
        {
            for ( SemanticLabel label : this.getLabels() )
            {
                this.addLabelToIdentifierCache(label);
            }
        }
        // else - There is no map so we don't put anything in the cache.
    }
    
    /**
     * Adds the given label to the cache of SemanticIdentifiers. This is used
     * so that the fast SemanticIdentifiers can be used by the converter 
     * instead of the SemanticLabel.
     *
     * @param  label The label to add.
     */
    protected void addLabelToIdentifierCache(
        SemanticLabel label)
    {
        if ( this.semanticIdentifierMap == null )
        {
            // No identifier map is specified.
            return;
        }
        
        // Get the identifier for the label and add it to the cache.
        SemanticIdentifier identifier = 
            this.getSemanticIdentifierMap().addLabel(label);
        int index = this.getIdentifiers().size();
        this.getIdentifiers().add(identifier);
        this.getIdentifierToIndexMap().put(identifier, index);
    }
    
    /**
     * {@inheritDoc}
     *
     * @param  cogxels {@inheritDoc}
     * @return {@inheritDoc}
     */
    public Vector fromCogxels(
        CogxelState cogxels)
    {
        // Validate the parameters.
        if ( cogxels == null )
        {
            throw new IllegalArgumentException("cogxels is null");
        }
        
        // Validate the state.
        if ( this.getSemanticIdentifierMap() == null )
        {
            throw new IllegalStateException(
                "The semanticIdentifierMap is not set.");
        }
        
        // Create the vectors to store the inputs and outputs.
        Vector vector = this.createEmptyVector();
        
        // Choose which way to iterate over the cogxels by figuring out how
        // many there are and how big the vector is.
        if ( cogxels.getNumCogxels() > this.getDimensionality() )
        {
            // This is optimized for the case when the number of labels in the
            // converter is less than the number of cogxels.
            int index = 0;
            for ( SemanticIdentifier identifier : this.getIdentifiers() )
            {
                double value = cogxels.getCogxelActivation(identifier);
                vector.setElement(index, value);
                index++;
            }
        }
        else
        {
            // This is optimized for the case where the majority of the Cogxels 
            // are expected to be zero.
            for ( Cogxel cogxel : cogxels )
            {
                // Get the index of the identifier.
                SemanticIdentifier identifier = cogxel.getSemanticIdentifier();

                int index = this.findIndexForIdentifier(identifier);

                if ( index < 0 )
                {
                    // Not a part of our vector.
                    continue;
                }

                // Get the cogxel.
                double value = cogxel.getActivation();
                vector.setElement(index, value);
            }
        }

        // Return the created vector.
        return vector;  
    }

    /**
     * {@inheritDoc}
     *
     * @param  data {@inheritDoc}
     * @param  cogxels {@inheritDoc}
     */
    public void toCogxels(
        Vector data,
        CogxelState cogxels)
    {
        // Validate the parameters.
        if ( data == null )
        {
            throw new IllegalArgumentException("data is null");
        }
        else if ( cogxels == null )
        {
            throw new IllegalArgumentException("cogxels is null");
        }

        // Validate the state.
        if ( this.getSemanticIdentifierMap() == null )
        {
            throw new IllegalStateException(
                "The semanticIdentifierMap is not set.");
        }
        
        // Make sure the given Vector is of the proper dimensionality.
        int dimensionality = data.getDimensionality();
        if ( dimensionality != this.getDimensionality() )
        {
            throw new DimensionalityMismatchException(dimensionality,
                this.getDimensionality());
        }
        
        // Copy the values into the CogxelState.
        CogxelFactory factory = this.getCogxelFactory();
        for (int i = 0; i < dimensionality; i++)
        {
            // Get the value from the i-th element of the vector.
            double value = data.getElement(i);
            
            // Get the i-th identifier.
            SemanticIdentifier identifier = this.getIdentifiers().get(i);
            
            // Get or create the Cogxel.
            Cogxel cogxel = 
                cogxels.getOrCreateCogxel(identifier, factory);
            
            // Set the Cogxel's activation.
            cogxel.setActivation(value);
        }
    }
    
    /**
     * Finds the vector index for the given SemanticIdentifier.
     *
     * @param  identifier The SemanticIdentifier to find the integer index for.
     * @return The integer index for the given SemanticIdentifier, if it is
     *         an identifier this converter is using; otherwise, -1.
     */
    protected int findIndexForIdentifier(
        SemanticIdentifier identifier)
    {
        // look for th index.
        Integer index = this.getIdentifierToIndexMap().get(identifier);
        
        if ( index == null )
        {
            // The index does not exist.
            return -1;
        }
        else
        {
            // The index was located.
            return index;
        }       
    }
    
    /**
     * {@inheritDoc}
     *
     * @param  other {@inheritDoc}
     * @return {@inheritDoc}
     */
    @Override
    public boolean equals(
        Object other)
    {
        if ( other instanceof CogxelVectorConverter )
        {
            return this.equals((CogxelVectorConverter) other);
        }
        else
        {   
            return false;
        }
    }
    
    /**
     * Returns true if the two converters have the same labels.
     *
     * @param  other Another CogxelVectorConverter.
     * @return True if the two converters have the same labels.
     */
    public boolean equals(
        CogxelVectorConverter other)
    {
        if ( other == null || other.getDimensionality() != this.getDimensionality() )
        {
            return false;
        }
        
        int length = this.getDimensionality();
        for (int i = 0; i < length; i++)
        {
            if ( !this.getLabels().get(i).equals(other.getLabels().get(i)) )
            {
                return false;
            }
        }
        
        return true;
    }

    @Override
    public int hashCode()
    {
        int hash = 7;
        if (!CollectionUtil.isEmpty(this.labels))
        {
            for (SemanticLabel label : this.labels)
            {
                hash = 43 * hash + ObjectUtil.hashCodeSafe(label);
            }
        }
        return hash;
    }
    
    /**
     * Creates an empty Vector for the converter, of the proper dimensionality.
     *
     * @return An empty Vector for the converter to use.
     */
    public Vector createEmptyVector()
    {
        return this.getVectorFactory().createVector(this.getDimensionality());
    }
    
    /**
     * Gets the dimensionality of the Vector created by the converter.
     *
     * @return The dimensionality of the Vector created by the converter.
     */
    public int getDimensionality()
    {
        return this.getLabels().size();
    }

    /**
     * {@inheritDoc}
     *
     * @return {@inheritDoc}
     */
    public SemanticIdentifierMap getSemanticIdentifierMap()
    {
        return semanticIdentifierMap;
    }
    
    /**
     * {@inheritDoc}
     *
     * @param  semanticIdentifierMap {@inheritDoc}
     */
    public void setSemanticIdentifierMap(
        SemanticIdentifierMap semanticIdentifierMap)
    {
        this.semanticIdentifierMap = semanticIdentifierMap;
        this.buildIdentifierCache();
    }

    /**
     * Gets the labels used by the converter, each one corresponding to one
     * dimension in the converted Vector.
     *
     * @return The labels used by the converter.
     */
    public ArrayList getLabels()
    {
        return this.labels;
    }
    
    /**
     * Sets the labels to be used by the converter, each one corresponding to 
     * one dimension in the converted Vector.
     *
     * @param labels The labels to be used by the converter.
     */
    public void setLabels(
        ArrayList labels)
    {
        this.labels = labels;
        this.buildIdentifierCache();
    }
    
    /**
     * Gets the list of cached SemanticIdentifiers.
     *
     * @return The list of cached SemanticIdentifiers.
     */
    protected ArrayList getIdentifiers()
    {
        return this.identifiers;
    }
    
    /**
     * Sets the list of cached SemanticIdentifiers.
     *
     * @param  identifiers The list of cached SemanticIdentifiers.
     */
    protected void setIdentifiers(
        ArrayList identifiers)
    {
        this.identifiers = identifiers;
    }
    
    /**
     * Gets the cached mapping of SemanticIdentifier to vector index.
     *
     * @return The cached mapping of SemanticIdentifier to vector index.
     */
    protected HashMap getIdentifierToIndexMap()
    {
        return this.identifierToIndexMap;
    }
    
    /**
     * Sets the cached mapping of SemanticIdentifier to vector index.
     *
     * @param   identifierToIndexMap The cached mapping of SemanticIdentifier 
     *          to vector index.
     */
    protected void setIdentifierToIndexMap(
        HashMap identifierToIndexMap)
    {
        this.identifierToIndexMap = identifierToIndexMap;
    }

    /**
     * Gets the CogxelFactory used to create the Cogxels used by the converter.
     *
     * @return The CogxelFactory used to create the Cogxels used by the 
     *         converter.
     */
    public CogxelFactory getCogxelFactory()
    {
        return this.cogxelFactory;
    }
    
    /**
     * Gets the CogxelFactory used to create the Cogxels used by the converter.
     *
     * @param  cogxelFactory The CogxelFactory used to create the Cogxels used  
     *         by the converter.
     */
    public void setCogxelFactory(
        CogxelFactory cogxelFactory)
    {
        this.cogxelFactory = cogxelFactory;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy