Package com.dtw

Source Code of com.dtw.SearchWindow$SearchWindowIterator

/*
* SearchWindow.java   Jul 14, 2004
*
* Copyright (c) 2004 Stan Salvador
* stansalvador@hotmail.com
*/

package com.dtw;

import com.matrix.ColMajorCell;

import java.util.Iterator;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.ConcurrentModificationException;
import java.util.NoSuchElementException;



abstract public class SearchWindow
{
   // PRIVATE DATA
   private final int[] minValues;
   private final int[] maxValues;
   private final int maxJ;
   private int size;
   private int modCount;



   // CONSTRUCTOR
   public SearchWindow(int tsIsize, int tsJsize)
   {
      minValues = new int[tsIsize];
      maxValues = new int[tsIsize];
      Arrays.fill(minValues, -1);
      maxJ = tsJsize-1;
      size = 0;
      modCount = 0;
   }



   // PUBLIC FUNCTIONS
   public final boolean isInWindow(int i, int j)
   {
      return (i>=minI()) && (i<=maxI()) && (minValues[i]<=j) && (maxValues[i]>=j);
   }


   public final int minI()
   {
      return 0;
   }


   public final int maxI()
   {
      return minValues.length-1;
   }


   public final int minJ()
   {
      return 0;
   }


   public final int maxJ()
   {
      return maxJ;
   }


   public final int minJforI(int i)
   {
      return minValues[i];
   }


   public final int maxJforI(int i)
   {
      return maxValues[i];
   }


   public final int size()
   {
      return size;
   }


   // Iterates through all cells in the search window in the order that Dynamic
   //    Time Warping needs to evaluate them. (first to last column (0..maxI),
   //    bottom up  (o..maxJ))
   public final Iterator iterator()
   {
      return new SearchWindowIterator(this);
   }


   public final String toString()
   {
      final StringBuffer outStr = new StringBuffer();

      for (int i=minI(); i<=maxI(); i++)
      {
         outStr.append("i=" + i + ", j=" + minValues[i] + "..." + maxValues[i]);
         if (i != maxI())
            outStr.append("\n");
      // end for loop

      return outStr.toString();
   // end toString()


   protected int getModCount()
   {
      return modCount;
   }



   // PROTECTED FUNCTIONS
   //    Expands the current window by a s pecified radius.
   protected final void expandWindow(int radius)
   {
      if (radius > 0)
      {
         // Expand the search window by one before expanding by the remainder of the radius because the function
         //    "expandSearchWindow(.) may not work correctly if the path has a width of only 1.
         expandSearchWindow(1);
         expandSearchWindow(radius-1);
      }
   }


   private final void expandSearchWindow(int radius)
   {
      if (radius > 0// if radius <=0 then no search is necessary, use the current search window
      {
         // Add all cells in the current Window to an array, iterating through the window and expanding the window
         //    at the same time is not possible because the window can't be changed during iteration through the cells.
         final ArrayList windowCells = new ArrayList(this.size());
         for (final Iterator cellIter=this.iterator(); cellIter.hasNext();)
            windowCells.add(cellIter.next());


         for (int cell=0; cell<windowCells.size(); cell++)
         {
            final ColMajorCell currentCell = (ColMajorCell)windowCells.get(cell);

            if ( (currentCell.getCol() != minI()) && (currentCell.getRow() != maxJ()) )// move to upper left if possible
            {
               // Either extend full search radius or some fraction until edges of matrix are met.
               final int targetCol = currentCell.getCol()-radius;
               final int targetRow = currentCell.getRow()+radius;

               if ( (targetCol>=minI()) && (targetRow<=maxJ()))
                  markVisited(targetCol, targetRow);
               else
               {
                  // Expand the window only to the edge of the matrix.
                  final int cellsPastEdge = Math.max(minI()-targetCol, targetRow-maxJ());
                  markVisited(targetCol+cellsPastEdge, targetRow-cellsPastEdge);
               // end if
            // end if

            if (currentCell.getRow() != maxJ())  // move up if possible
            {
               // Either extend full search radius or some fraction until edges of matrix are met.
               final int targetCol = currentCell.getCol();
               final int targetRow = currentCell.getRow()+radius;

               if (targetRow <= maxJ())
                  markVisited(targetCol, targetRow)// radius does not go past the edges of the matrix
               else
               {
                  // Expand the window only to the edge of the matrix.
                  final int cellsPastEdge = targetRow-maxJ();
                  markVisited(targetCol, targetRow-cellsPastEdge);
               // end if
            // end if

            if ((currentCell.getCol() != maxI()) && (currentCell.getRow() != maxJ())) // move to upper-right if possible
            {
               // Either extend full search radius or some fraction until edges of matrix are met.
               final int targetCol = currentCell.getCol()+radius;
               final int targetRow = currentCell.getRow()+radius;

               if ( (targetCol<=maxI()) && (targetRow<=maxJ()))
                  markVisited(targetCol, targetRow)// radius does not go past the edges of the matrix
               else
               {
                  // Expand the window only to the edge of the matrix.
                  final int cellsPastEdge = Math.max(targetCol-maxI(), targetRow-maxJ());
                  markVisited(targetCol-cellsPastEdge, targetRow-cellsPastEdge);
               // end if
            // end if

            if (currentCell.getCol() != minI())  // move left if possible
            {
               // Either extend full search radius or some fraction until edges of matrix are met.
               final int targetCol = currentCell.getCol()-radius;
               final int targetRow = currentCell.getRow();

               if (targetCol >= minI())
                  markVisited(targetCol, targetRow)// radius does not go past the edges of the matrix
               else
               {
                  // Expand the window only to the edge of the matrix.
                  final int cellsPastEdge = minI()-targetCol;
                  markVisited(targetCol+cellsPastEdge, targetRow);
               // end if
            // end if

            if (currentCell.getCol() != maxI())  // move right if possible
            {
               // Either extend full search radius or some fraction until edges of matrix are met.
               final int targetCol = currentCell.getCol()+radius;
               final int targetRow = currentCell.getRow();

               if (targetCol <= maxI())
                  markVisited(targetCol, targetRow)// radius does not go past the edges of the matrix
               else
               {
                  // Expand the window only to the edge of the matrix.
                  final int cellsPastEdge = targetCol-maxI();
                  markVisited(targetCol-cellsPastEdge, targetRow);
               // end if
            // end if

            if ( (currentCell.getCol() != minI()) && (currentCell.getRow() != minJ()) )  // move to lower-left if possible
            {
               // Either extend full search radius or some fraction until edges of matrix are met.
               final int targetCol = currentCell.getCol()-radius;
               final int targetRow = currentCell.getRow()-radius;

               if ( (targetCol>=minI()) && (targetRow>=minJ()))
                  markVisited(targetCol, targetRow)// radius does not go past the edges of the matrix
               else
               {
                  // Expand the window only to the edge of the matrix.
                  final int cellsPastEdge = Math.max(minI()-targetCol, minJ()-targetRow);
                  markVisited(targetCol+cellsPastEdge, targetRow+cellsPastEdge);
               // end if
            // end if

            if (currentCell.getRow() != minJ())  // move down if possible
            {
               // Either extend full search radius or some fraction until edges of matrix are met.
               final int targetCol = currentCell.getCol();
               final int targetRow = currentCell.getRow()-radius;

               if (targetRow >= minJ())
                  markVisited(targetCol, targetRow)// radius does not go past the edges of the matrix
               else
               {
                  // Expand the window only to the edge of the matrix.
                  final int cellsPastEdge = minJ()-targetRow;
                  markVisited(targetCol, targetRow+cellsPastEdge);
               // end if
            // end if

            if ((currentCell.getCol() != maxI()) && (currentCell.getRow() != minJ()))  // move to lower-right if possible
            {
               // Either extend full search radius or some fraction until edges of matrix are met.
               final int targetCol = currentCell.getCol()+radius;
               final int targetRow = currentCell.getRow()-radius;

               if ( (targetCol<=maxI()) && (targetRow>=minJ()))
                  markVisited(targetCol, targetRow)// radius does not go past the edges of the matrix
               else
               {
                  // Expand the window only to the edge of the matrix.
                  final int cellsPastEdge = Math.max(targetCol-maxI(), minJ()-targetRow);
                  markVisited(targetCol-cellsPastEdge, targetRow+cellsPastEdge);
               // end if
            // end if
         // end for loop
      // end if
   // end expandWindow(.)


   // Raturns true if the window is modified.
   protected final void markVisited(int col, int row)
   {
      if (minValues[col] == -1)       // first value is entered in the column
      {
         minValues[col] = row;
         maxValues[col] = row;
         this.size++;
         modCount++;  // stucture has been changed
         //return true;
      }
      else if (minValues[col] > row// minimum range in the column is expanded
      {
         this.size += minValues[col]-row;
         minValues[col] = row;
         modCount++;  // stucture has been changed
      }
      else if (maxValues[col] < row) // maximum range in the column is expanded
      {
         this.size += row-maxValues[col];
         maxValues[col] = row;
         modCount++;
      // end if
   // end markVisited(.)





   // A private class that is a fail-fast iterator through the search window.
   private final class SearchWindowIterator implements Iterator
   {
      // PRIVATE DATA
      private int currentI;
      private int currentJ;
      private final SearchWindow window;
      private boolean hasMoreElements;
      private final int expectedModCount;


      // CONSTRUCTOR
      private SearchWindowIterator(SearchWindow w)
      {
         // Intiialize values
         window = w;
         hasMoreElements = window.size()>0;
         currentI = window.minI();
         currentJ = window.minJ();
         expectedModCount = w.modCount;
      }


      // PUBLIC FUNCTIONS
      public boolean hasNext()
      {
         return hasMoreElements;
      }


      public Object next()
      {
         if (modCount != expectedModCount)
            throw new ConcurrentModificationException();
         else if (!hasMoreElements)
            throw new NoSuchElementException();
         else
         {
            final ColMajorCell cell = new ColMajorCell(currentI, currentJ);
            if (++currentJ > window.maxJforI(currentI))
            {
               if (++currentI <= window.maxI())
                  currentJ = window.minJforI(currentI);
               else
                  hasMoreElements = false;
            // end if
            return cell;
         // end if
      // end next()


      public void remove()
      {
         throw new UnsupportedOperationException();
      }
   }  // end inner class SearchWindowIterator


// end SearchWindow
TOP

Related Classes of com.dtw.SearchWindow$SearchWindowIterator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.