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

gov.sandia.cognition.math.matrix.VectorUnionIterator Maven / Gradle / Ivy

There is a newer version: 4.0.1
Show newest version
/*
 * File:                VectorUnionIterator.java
 * Authors:             Kevin R. Dixon
 * 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.math.matrix;

import gov.sandia.cognition.annotation.CodeReview;
import java.util.Iterator;
import java.util.NoSuchElementException;

/**
 * Iterator that returns all nonzero entries for either underlying Vector
 *
 * @author Kevin R. Dixon
 * @since  1.0
 */
@CodeReview(
    reviewer="Jonathan McClain",
    date="2006-05-17",
    changesNeeded=false,
    comments="Looks fine."
)
public class VectorUnionIterator
    implements Iterator
{
    
    /**
     * Iterator from the first Vector
     */
    private Iterator firstIterator;
    /**
     * Iterator from the second Vector
     */
    private Iterator secondIterator;
    
    /**
     * TwoVectorEntry that represents entries from both Vectors
     */
    private TwoVectorEntry internalEntry;
    
    /**
     * VectorEntry from the first Vector
     */
    private VectorEntry firstInternalEntry;
    /**
     * VectorEntry from the second Vector
     */
    private VectorEntry secondInternalEntry;
    
    /**
     * Creates a new instance of VectorUnionIterator.
     *
     * @param  first The first Vector.
     * @param  second The second Vector.
     */
    public VectorUnionIterator(
        final Vector first,
        final Vector second)
    {
        this(first.iterator(), second.iterator(), 
            new DefaultTwoVectorEntry(first, second));
    }
    
    /**
     * Creates a new instance of VectorUnionIterator
     * @param firstIterator Iterator from the first Vector
     * @param secondIterator Iterator from the second Vector
     * @param internalEntry TwoVectorEntry that represents entries from both Vectors
     */
    public VectorUnionIterator(
        final Iterator firstIterator,
        final Iterator secondIterator,
        final TwoVectorEntry internalEntry)
    {
        this.setFirstIterator( firstIterator );
        this.setSecondIterator( secondIterator );
        this.setInternalEntry( internalEntry );
        
        this.setFirstInternalEntry( null );
        this.setSecondInternalEntry( null );
    }

    /**
     * Internal method for advancing the internal Iterators
     */
    protected void advanceInternalIterators()
    {
        
        boolean advanceFirst = false;
        boolean advanceSecond = false;
        
        EntryIndexComparator.Compare compare =
            VectorEntryIndexComparator.INSTANCE.lowestIndex(
                this.getFirstInternalEntry(), this.getSecondInternalEntry() );
        
        if( compare == EntryIndexComparator.Compare.FIRST_LOWEST )
        {
            advanceFirst = true;
        }
        else if( compare == EntryIndexComparator.Compare.SECOND_LOWEST )
        {
            advanceSecond = true;
        }
        else if( compare == EntryIndexComparator.Compare.FIRST_ENTRY_NULL )
        {
            advanceSecond = true;
        }
        else if( compare == EntryIndexComparator.Compare.SECOND_ENTRY_NULL )
        {
            advanceFirst = true;
        }
        else if( compare == EntryIndexComparator.Compare.BOTH_ENTRIES_NULL )
        {
            advanceFirst = true;
            advanceSecond = true;
        }
        else if( compare == EntryIndexComparator.Compare.ENTRIES_EQUAL )
        {
            advanceFirst = true;
            advanceSecond = true;
        }        
        else
        {
            throw new NoSuchElementException(
                "Unknown Compare Enum: " + compare );
         }
            

        if( (advanceFirst == false) &&
            (advanceSecond == false) )
        {
            throw new NoSuchElementException(
                "Problem: Not advancing any iterators..." );
        }
        
        if( advanceFirst )
        {
            this.safeFirstNext();
        }
        
        if( advanceSecond )
        {
            this.safeSecondNext();
        }
                
    }
    
    /**               
     * Try to advance the first entry... if the iterator throws an
     * exception, then there are no more elements in the vector,
     * so just null out the entry
     *
     * @return true if next was valid, false otherwise
     */
    public boolean safeFirstNext()
    {
        boolean valid_next = false;
        
        try
        {
            if (this.getFirstIterator().hasNext())
            {
                this.setFirstInternalEntry( this.getFirstIterator().next() );
                valid_next = true;
            }
            else
            {
                this.setFirstInternalEntry(null);
            }
        }
        catch (Exception e)
        {
            this.setFirstInternalEntry( null );
        }
        
        return valid_next;
        
    }

    /**               
     * Try to advance the second entry... if the iterator throws an
     * exception, then there are no more elements in the vector,
     * so just null out the entry
     *
     * @return true if next was valid, false otherwise
     */
    public boolean safeSecondNext()
    {
        boolean valid_next = false;
        
        try
        {
            if (this.getSecondIterator().hasNext())
            {
                this.setSecondInternalEntry( this.getSecondIterator().next() );
                valid_next = true;
            }
            else
            {
                this.setSecondInternalEntry(null);
            }
        }
        catch (Exception e)
        {
            this.setSecondInternalEntry( null );
        }
        
        return valid_next;
        
    }    
    
    
    /**
     * getter for firstIterator
     * @return Iterator from the first Vector
     */
    public Iterator getFirstIterator()
    {
        return this.firstIterator;
    }

    /**
     * setter for firstIterator
     * @param firstIterator Iterator from the first Vector
     */
    public void setFirstIterator(
        final Iterator firstIterator)
    {
        this.firstIterator = firstIterator;
    }

    /**
     * getter for secondIterator
     * @return Iterator from the second Vector
     */
    public Iterator getSecondIterator()
    {
        return this.secondIterator;
    }

    /**
     * setter for secondIterator
     * @param secondIterator Iterator from the second Vector
     */
    public void setSecondIterator(
        final Iterator secondIterator)
    {
        this.secondIterator = secondIterator;
    }

    /**
     * getter for internalEntry
     * @return TwoVectorEntry that represents both Vectors
     */
    public TwoVectorEntry getInternalEntry()
    {
        return this.internalEntry;
    }

    /**
     * setter for internalEntry
     * @param internalEntry TwoVectorEntry that represents entries from both Vectors
     */
    public void setInternalEntry(
        final TwoVectorEntry internalEntry)
    {
        this.internalEntry = internalEntry;
    }

    /**
     * getter for firstInternalEntry
     * @return VectorEntry from the first Vector
     */
    public VectorEntry getFirstInternalEntry()
    {
        return this.firstInternalEntry;
    }

    /**
     * setter for firstInternalEntry
     * @param firstInternalEntry VectorEntry from the first Vector
     */
    public void setFirstInternalEntry(
        final VectorEntry firstInternalEntry)
    {
        this.firstInternalEntry = firstInternalEntry;
    }

    /**
     * getter for secondInternalEntry
     * @return VectorEntry from the second Vector
     */
    public VectorEntry getSecondInternalEntry()
    {
        return this.secondInternalEntry;
    }

    /**
     * setter for secondInternalEntry
     * @param secondInternalEntry VectorEntry from the second Vector
     */
    public void setSecondInternalEntry(
        final VectorEntry secondInternalEntry)
    {
        this.secondInternalEntry = secondInternalEntry;
    }
    
    @Override
    public boolean hasNext()
    {
        return 
               this.getFirstIterator().hasNext()
            || this.getSecondIterator().hasNext()
            || (this.firstInternalEntry != null && this.secondInternalEntry != null
                && this.firstInternalEntry.getIndex() != this.secondInternalEntry.getIndex());
    }

    @Override
    public TwoVectorEntry next()
    {
        
        this.advanceInternalIterators();
        
        EntryIndexComparator.Compare compare = 
            VectorEntryIndexComparator.INSTANCE.lowestIndex(
                this.getFirstInternalEntry(), this.getSecondInternalEntry() );
        
        if( compare == EntryIndexComparator.Compare.ENTRIES_EQUAL )
        {
            this.getInternalEntry().setIndex(
                this.getFirstInternalEntry().getIndex() );
        }
        else if( compare == EntryIndexComparator.Compare.FIRST_LOWEST )
        {
            this.getInternalEntry().setIndex(
                this.getFirstInternalEntry().getIndex() );
        }
        else if( compare == EntryIndexComparator.Compare.SECOND_LOWEST )
        {
            this.getInternalEntry().setIndex(
                this.getSecondInternalEntry().getIndex() );
        }
        else if( compare == EntryIndexComparator.Compare.FIRST_ENTRY_NULL )
        {
            this.getInternalEntry().setIndex(
                this.getSecondInternalEntry().getIndex() );
        }
        else if( compare == EntryIndexComparator.Compare.SECOND_ENTRY_NULL )
        {
            this.getInternalEntry().setIndex(
                this.getFirstInternalEntry().getIndex() );
        }
        else
        {
            throw new NoSuchElementException( "No elements remaining." );
        }

        return this.getInternalEntry();
        
    }

    @Override
    public void remove()
    {
        this.getInternalEntry().setFirstValue( 0.0 );
        this.getInternalEntry().setSecondValue( 0.0 );
    }
    
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy