docs: protected float findFlow( int cx , int cy , T curr , ImageFlow.D flow ) {
  		float bestScore = Float.MAX_VALUE;
  		int bestFlowX=0,bestFlowY=0;
  
  		// ensure the search region is contained entirely inside the image
  		int startY = cy-searchRadius-regionRadius < 0 ? Math.max(regionRadius - cy, 0) : -searchRadius;
  		int startX = cx-searchRadius-regionRadius < 0 ? Math.max(regionRadius-cx,0) : -searchRadius;
  		int endY = cy+searchRadius+regionRadius >= curr.height ? curr.height-cy-regionRadius-1 : searchRadius;
  		int endX = cx+searchRadius+regionRadius >= curr.width ? curr.width-cx-regionRadius-1 : searchRadius;
  
  		// search around the template's center
  		for( int i = startY; i <= endY; i++ ) {
  			int y = cy+i;
  			for( int j = startX; j <= endX; j++ ) {
  				int x = cx+j;
  				float error = computeError(x,y,curr);
  				if( error < bestScore ) {
  					bestScore = error;
  					bestFlowX = j;
  					bestFlowY = i;
  				} else if ( error == bestScore ) {
  					// Pick solution with the least motion when ambiguous
  					float m0 = j*j + i*i;
  					float m1 = bestFlowX*bestFlowX + bestFlowY*bestFlowY;
  					if( m0 < m1 ) {
  						bestFlowX = j;
  						bestFlowY = i;
  					}
  				}
  			}
  		}
  
  		if( bestScore <= maxError ) {
  			flow.x = bestFlowX;
  			flow.y = bestFlowY;
  			return bestScore;
  		} else {
  			flow.markInvalid();
  			return Float.NaN;
  		}
  	}