public IndexPair calculateIndexedDimensions()

in src/main/java/org/apache/sysds/parser/IndexedIdentifier.java [76:519]


	public IndexPair calculateIndexedDimensions(HashMap<String,DataIdentifier> ids, HashMap<String, ConstIdentifier> currConstVars, boolean conditional) 
	{
		// stores the updated row / col dimension info
		long updatedRowDim = -1, updatedColDim = -1;
		
		boolean isConst_rowLowerBound = false;
		boolean isConst_rowUpperBound = false;
		boolean isConst_colLowerBound = false;
		boolean isConst_colUpperBound = false;
		
		//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// STEP 1 : perform constant propagation for index boundaries
		//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// PROCESS ROW LOWER BOUND
		//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		// process row lower bound
		if (_rowLowerBound instanceof ConstIdentifier && ( _rowLowerBound instanceof IntIdentifier || _rowLowerBound instanceof DoubleIdentifier )){
			
			Long rowLB_1_1 = -1L;
			if (_rowLowerBound instanceof IntIdentifier) 
				rowLB_1_1 = ((IntIdentifier)_rowLowerBound).getValue();
			else 
				rowLB_1_1 = UtilFunctions.toLong(((DoubleIdentifier)_rowLowerBound).getValue());
				
			if (rowLB_1_1 < 1){
				raiseValidateError("lower-bound row index " + rowLB_1_1 + " initialized to out of bounds value. Value must be >= 1", conditional);
			}
			if ((this.getOrigDim1() >= 0)  && (rowLB_1_1 > this.getOrigDim1())) {
				raiseValidateError("lower-bound row index " + rowLB_1_1 + " initialized to out of bounds value.  Rows in " + this.getName() + ": " + this.getOrigDim1(), conditional);
			}
			// valid lower row bound value
			isConst_rowLowerBound = true;
		}
		else if (_rowLowerBound instanceof ConstIdentifier && !getDataType().isList() ) {
			raiseValidateError("assign lower-bound row index for Indexed Identifier " + this.toString() + " the non-numeric value " + _rowLowerBound.toString(), conditional);
		}
	
		// perform constant propogation for row lower bound
		else if (_rowLowerBound != null && _rowLowerBound instanceof DataIdentifier && !(_rowLowerBound instanceof IndexedIdentifier)) {
			String identifierName = ((DataIdentifier)_rowLowerBound).getName();
			
			// CASE: rowLowerBound is a constant DataIdentifier
			if (currConstVars.containsKey(identifierName) && !conditional){
				ConstIdentifier constValue = currConstVars.get(identifierName);
				
				if (!(constValue instanceof IntIdentifier || constValue instanceof DoubleIdentifier ))
					LOG.info(this.printInfoLocation() + "attempted to assign lower row bound for " + this.toString() + "the non-numeric value " + constValue.getOutput().toString() + " assigned to " + identifierName + ". May cause runtime exception ");
	
				else {
					
					// test constant propogation			
					long tempRowLB = -1L;
					boolean validRowLB = true;
					if (constValue instanceof IntIdentifier) 
						tempRowLB = ((IntIdentifier)constValue).getValue();
					else
						tempRowLB = UtilFunctions.toLong(((DoubleIdentifier)constValue).getValue());
							
					if (tempRowLB < 1){
						LOG.info(this.printInfoLocation() + "lower-bound row index " + identifierName + " initialized to "  + tempRowLB + " May cause runtime exception (runtime value must be >= 1)");	
						validRowLB = false;
					}
					if (this.getOrigDim1() >= 0  && tempRowLB > this.getOrigDim1()){ 
						LOG.info(this.printInfoLocation() + "lower-bound row index " + identifierName 
								+ " initialized to " + tempRowLB + " May cause runtime exception (Rows in " 
								+ this.getName() + ": " + this.getOrigDim1() +")");
						validRowLB = false;
					}	
					
					if (validRowLB) {
						if (constValue instanceof IntIdentifier) {
							_rowLowerBound = new IntIdentifier((IntIdentifier) constValue, constValue);
						} else {
							_rowLowerBound = new DoubleIdentifier((DoubleIdentifier) constValue, constValue);
						}
						isConst_rowLowerBound = true;
					}
				} // end else -- if (!(constValue instanceof IntIdentifier || constValue instanceof DoubleIdentifier ))				
			} // end if (currConstVars.containsKey(identifierName))		
		} // end constant propogation for row LB
		
		// check 1 < indexed row lower-bound < rows in IndexedIdentifier 
		// (assuming row dims available for upper bound)
		Long rowLB_1 = -1L;
		if (isConst_rowLowerBound) {
				
			if (_rowLowerBound instanceof IntIdentifier) 
				rowLB_1 = ((IntIdentifier)_rowLowerBound).getValue();
			else
				rowLB_1 = UtilFunctions.toLong(((DoubleIdentifier)_rowLowerBound).getValue());
		}
			
		
		
		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// PROCESS ROW UPPER BOUND
		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		if (_rowUpperBound instanceof ConstIdentifier && ( _rowUpperBound instanceof IntIdentifier || _rowUpperBound instanceof DoubleIdentifier )){
			
			Long rowUB_1_1 = -1L;
			if (_rowUpperBound instanceof IntIdentifier) 
				rowUB_1_1 = ((IntIdentifier)_rowUpperBound).getValue();
			else 
				rowUB_1_1 = UtilFunctions.toLong(((DoubleIdentifier)_rowUpperBound).getValue());
				
			if (rowUB_1_1 < 1){
				raiseValidateError("upper-bound row index " + rowUB_1_1 + " out of bounds value. Value must be >= 1", conditional);
			}
			if ((this.getOrigDim1() >= 0)  && (rowUB_1_1 > this.getOrigDim1())) {
				raiseValidateError("upper-bound row index " + rowUB_1_1 + " out of bounds value.  Rows in " + this.getName() + ": " + this.getOrigDim1(), conditional);
			}
			if (isConst_rowLowerBound && rowUB_1_1 < rowLB_1){
				raiseValidateError("upper-bound row index " + rowUB_1_1 + " greater than lower-bound row index " + rowLB_1, conditional);
			}
			isConst_rowUpperBound = true;
		}	
		else if (_rowUpperBound instanceof ConstIdentifier && !getDataType().isList()){
			raiseValidateError("assign upper-bound row index for " + this.toString() + " the non-numeric value " + _rowUpperBound.toString(), conditional);
		}
		
		// perform constant propogation for upper row index
		else if (_rowUpperBound != null && _rowUpperBound instanceof DataIdentifier && !(_rowUpperBound instanceof IndexedIdentifier)) {
			String identifierName = ((DataIdentifier)_rowUpperBound).getName();
			
			if (currConstVars.containsKey(identifierName) && !conditional){
				ConstIdentifier constValue = currConstVars.get(identifierName);
				
				if (!(constValue instanceof IntIdentifier || constValue instanceof DoubleIdentifier ))
					LOG.info(this.printInfoLocation() + "attempted to assign upper row bound for " + this.toString() + "the non-numeric value " + constValue.getOutput().toString() + " assigned to " + identifierName + ". May cause runtime exception ");
	
				else {						
					// test constant propogation			
					long tempRowUB = -1L;
					boolean validRowUB = true;
					if (constValue instanceof IntIdentifier) 
						tempRowUB = ((IntIdentifier)constValue).getValue();
					else
						tempRowUB = UtilFunctions.toLong(((DoubleIdentifier)constValue).getValue());
							
					if (tempRowUB < 1){
						LOG.info(this.printInfoLocation() + "upper-bound row index " + identifierName + " initialized to "  + tempRowUB + " May cause runtime exception (runtime value must be >= 1)");	
						validRowUB = false;
					}
					if (this.getOrigDim1() >= 0  && tempRowUB > this.getOrigDim1()){ 
						LOG.info(this.printInfoLocation() + "upper-bound row index " + identifierName + " initialized to "  + tempRowUB + " May cause runtime exception (Rows in " + this.getName() + ": " + this.getOrigDim1() +")");
						validRowUB = false;
					}	
					if (isConst_rowLowerBound && tempRowUB < rowLB_1){
						LOG.info(this.printInfoLocation() + "upper-bound row index " 
								+ identifierName + " initialized to " +  tempRowUB 
								+ ", which is greater than lower-bound row index value " 
								+ rowLB_1 + " May cause runtime exception");
						validRowUB = false;
					}

					if (validRowUB) {
						if (constValue instanceof IntIdentifier) {
							_rowUpperBound = new IntIdentifier((IntIdentifier) constValue, constValue);
						} else {
							_rowUpperBound = new DoubleIdentifier((DoubleIdentifier) constValue, constValue);
						}
						isConst_rowUpperBound = true;
					}
				} // end else -- if (!(constValue instanceof IntIdentifier || constValue instanceof DoubleIdentifier ))
			} // end if (currConstVars.containsKey(identifierName)){
			
		} // end constant propagation for row UB	
		
		
		//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// PROCESS COLUMN LOWER BOUND
		//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		// process column lower bound
		if (_colLowerBound instanceof ConstIdentifier && ( _colLowerBound instanceof IntIdentifier || _colLowerBound instanceof DoubleIdentifier )){
			
			Long colLB_1_1 = -1L;
			if (_colLowerBound instanceof IntIdentifier) 
				colLB_1_1 = ((IntIdentifier)_colLowerBound).getValue();
			else 
				colLB_1_1 = UtilFunctions.toLong(((DoubleIdentifier)_colLowerBound).getValue());
				
			if (colLB_1_1 < 1){
				raiseValidateError("lower-bound column index " + colLB_1_1 + " initialized to out of bounds value. Value must be >= 1", conditional);
			}
			if ((this.getOrigDim2() >= 0)  && (colLB_1_1 > this.getOrigDim2())){ 
				raiseValidateError("lower-bound column index " + colLB_1_1 + " initialized to out of bounds value.  Columns in " + this.getName() + ": " + this.getOrigDim2(), conditional);
			}
			// valid lower row bound value
			isConst_colLowerBound = true;
		}
			
		else if (_colLowerBound instanceof ConstIdentifier && !getDataType().isList()) {
			raiseValidateError("assign lower-bound column index for Indexed Identifier " + this.toString() + " the non-numeric value " + _colLowerBound.toString(), conditional);
		}
		
		// perform constant propogation for column lower bound
		else if (_colLowerBound != null && _colLowerBound instanceof DataIdentifier && !(_colLowerBound instanceof IndexedIdentifier)) {
			String identifierName = ((DataIdentifier)_colLowerBound).getName();
			if (currConstVars.containsKey(identifierName) && !conditional){
				ConstIdentifier constValue = currConstVars.get(identifierName);
				
				if (!(constValue instanceof IntIdentifier || constValue instanceof DoubleIdentifier ))
					LOG.info(this.printInfoLocation() + "attempted to assign lower column bound for " + this.toString() + "the non-numeric value " + constValue.getOutput().toString() + " assigned to " + identifierName + ". May cause runtime exception ");
	
				else {
					
					// test constant propogation			
					long tempColLB = -1L;
					boolean validColLB = true;
					if (constValue instanceof IntIdentifier) 
						tempColLB = ((IntIdentifier)constValue).getValue();
					else
						tempColLB = UtilFunctions.toLong(((DoubleIdentifier)constValue).getValue());
							
					if (tempColLB < 1){
						LOG.info(this.printInfoLocation() + "lower-bound column index " + identifierName + " initialized to "  + tempColLB + " May cause runtime exception (runtime value must be >= 1)");	
						validColLB = false;
					}
					if (this.getOrigDim2() >= 0  && tempColLB > this.getOrigDim2()){ 
						LOG.info(this.printInfoLocation() + "lower-bound column index " 
								+ identifierName + " initialized to " + tempColLB 
								+ " May cause runtime exception (Columns in " + this.getName() 
								+ ": " + this.getOrigDim2() +")");
						validColLB = false;
					}	

					if (validColLB) {
						if (constValue instanceof IntIdentifier) {
							_colLowerBound = new IntIdentifier((IntIdentifier) constValue, constValue);
						} else {
							_colLowerBound = new DoubleIdentifier((DoubleIdentifier) constValue, constValue);
						}
						isConst_colLowerBound = true;
					}
				} // end else -- if (!(constValue instanceof IntIdentifier || constValue instanceof DoubleIdentifier ))
			} 	
		} // end constant propogation for column LB
		
		// check 1 < indexed column lower-bound < columns in IndexedIdentifier 
		// (assuming column dims available for upper bound)
		Long colLB_1 = -1L;
		if (isConst_colLowerBound) {
				
			if (_colLowerBound instanceof IntIdentifier) 
				colLB_1 = ((IntIdentifier)_colLowerBound).getValue();
			else
				colLB_1 = UtilFunctions.toLong(((DoubleIdentifier)_colLowerBound).getValue());
		}
			
		
		
		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// PROCESS ROW UPPER BOUND
		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		if (_colUpperBound instanceof ConstIdentifier && ( _colUpperBound instanceof IntIdentifier || _colUpperBound instanceof DoubleIdentifier )){
			
			Long colUB_1_1 = -1L;
			if (_colUpperBound instanceof IntIdentifier) 
				colUB_1_1 = ((IntIdentifier)_colUpperBound).getValue();
			else 
				colUB_1_1 = UtilFunctions.toLong(((DoubleIdentifier)_colUpperBound).getValue());
				
			if (colUB_1_1 < 1){
				raiseValidateError("upper-bound column index " + colUB_1_1 + " out of bounds value. Value must be >= 1", conditional);
			}
			if ((this.getOrigDim2() >= 0)  && (colUB_1_1 > this.getOrigDim2())) {
				raiseValidateError("upper-bound column index " + colUB_1_1 + " out of bounds value.  Columns in " + this.getName() + ": " + this.getOrigDim2(), conditional);
			}
			if (isConst_rowLowerBound && colUB_1_1 < colLB_1) {
				raiseValidateError("upper-bound column index " + colUB_1_1 + " greater than lower-bound row index " + colLB_1, conditional);
			}
		    	
			isConst_colUpperBound = true;
		}	
		else if (_colUpperBound instanceof ConstIdentifier && !getDataType().isList()){	
			raiseValidateError("assign upper-bound column index for " + this.toString() + " the non-numeric value " + _colUpperBound.toString(), conditional);
		}
		
		// perform constant propogation for upper row index
		else if (_colUpperBound != null && _colUpperBound instanceof DataIdentifier 
				&& !(_colUpperBound instanceof IndexedIdentifier)) {
			String identifierName = ((DataIdentifier)_colUpperBound).getName();
			
			
			if (currConstVars.containsKey(identifierName) && !conditional){
				ConstIdentifier constValue = currConstVars.get(identifierName);
				
				if (!(constValue instanceof IntIdentifier || constValue instanceof DoubleIdentifier ))
					LOG.info(this.printInfoLocation() + "attempted to assign upper column bound for " 
							+ this.toString() + "the non-numeric value " + constValue.getOutput().toString() 
							+ " assigned to " + identifierName + ". May cause runtime exception ");
	
				else {						
					// test constant propogation			
					long tempColUB = -1L;
					boolean validColUB = true;
					if (constValue instanceof IntIdentifier) 
						tempColUB = ((IntIdentifier)constValue).getValue();
					else
						tempColUB = UtilFunctions.toLong(((DoubleIdentifier)constValue).getValue());
							
					if (tempColUB < 1){
						LOG.info(this.printInfoLocation() + "upper-bound column index " 
								+ identifierName + " initialized to "  + tempColUB 
								+ " May cause runtime exception (runtime value must be >= 1)");	
						validColUB = false;
					}
					if (this.getOrigDim2() >= 0  && tempColUB > this.getOrigDim2()){ 
						LOG.info(this.printInfoLocation() + "upper-bound column index " 
								+ identifierName + " initialized to "  + tempColUB 
								+ " May cause runtime exception (Columns in " + this.getName() 
								+ ": " + this.getOrigDim2() + ")");
						validColUB = false;
					}	
					if (isConst_colLowerBound && tempColUB < colLB_1){
						LOG.info(this.printInfoLocation() + "upper-bound column index " 
					+ identifierName + " initialized to " +  tempColUB 
					+ ", which is greater than lower-bound column index value " + colLB_1 
					+ " May cause runtime exception");
						validColUB = false;
					}

					if (validColUB) {
						if (constValue instanceof IntIdentifier) {
							_colUpperBound = new IntIdentifier((IntIdentifier) constValue, constValue);
						} else {
							_colUpperBound = new DoubleIdentifier((DoubleIdentifier) constValue, constValue);
						}
						isConst_colUpperBound = true;
					}
				} // end else -- if (!(constValue instanceof IntIdentifier || constValue instanceof DoubleIdentifier ))
			}	
		} // end constant propagation for column UB	
		
		///////////////////////////////////////////////////////////////////////
		// STEP 2: update row dimensions
		///////////////////////////////////////////////////////////////////////
			
		// CASE:  lower == upper --> updated row dim = 1
		if (_rowLowerEqualsUpper) 
			updatedRowDim = 1;
		
		// CASE: (lower == null && upper == null) --> updated row dim = (rows of input)
		else if (_rowLowerBound == null && _rowUpperBound == null){
			updatedRowDim = this.getOrigDim1(); 
		}
		
		// CASE: (lower == null) && (upper == constant) --> updated row dim = (constant)
		else if (_rowLowerBound == null && isConst_rowUpperBound) {
			if (_rowUpperBound instanceof IntIdentifier)
				updatedRowDim = ((IntIdentifier)_rowUpperBound).getValue();
			else if (_rowUpperBound instanceof DoubleIdentifier)
				updatedRowDim = UtilFunctions.toLong(((DoubleIdentifier)_rowUpperBound).getValue());
		}
			
		// CASE: (lower == constant) && (upper == null) && (dimIndex > 0) --> rowCount - lower bound + 1
		else if (isConst_rowLowerBound && _rowUpperBound == null && this.getOrigDim1() >= 0) {
			long rowCount = this.getOrigDim1();
			if (_rowLowerBound instanceof IntIdentifier)
				updatedRowDim = rowCount - ((IntIdentifier)_rowLowerBound).getValue() + 1;
			else if (_rowLowerBound instanceof DoubleIdentifier)
				updatedRowDim = UtilFunctions.toLong(rowCount - ((DoubleIdentifier)_rowLowerBound).getValue() + 1);
		}
		// CASE: (lower == constant) && (upper == constant) --> upper bound - lower bound + 1
		else if (isConst_rowLowerBound && isConst_rowUpperBound) {
			if (_rowLowerBound instanceof IntIdentifier && _rowUpperBound instanceof IntIdentifier)
				updatedRowDim = ((IntIdentifier)_rowUpperBound).getValue() - ((IntIdentifier)_rowLowerBound).getValue() + 1;
			
			else if (_rowLowerBound instanceof DoubleIdentifier && _rowUpperBound instanceof DoubleIdentifier)
				updatedRowDim = UtilFunctions.toLong( ((DoubleIdentifier)_rowUpperBound).getValue() - ((DoubleIdentifier)_rowLowerBound).getValue() + 1);
			
			else if (_rowLowerBound instanceof IntIdentifier && _rowUpperBound instanceof DoubleIdentifier)
				updatedRowDim = UtilFunctions.toLong( ((DoubleIdentifier)_rowUpperBound).getValue() - ((IntIdentifier)_rowLowerBound).getValue() + 1);
			
			else if (_rowLowerBound instanceof DoubleIdentifier && _rowUpperBound instanceof IntIdentifier)
				updatedRowDim = UtilFunctions.toLong( ((IntIdentifier)_rowUpperBound).getValue() - ((DoubleIdentifier)_rowLowerBound).getValue() + 1);
			
		}
		
		// CASE: row dimension is unknown --> assign -1
		else{ 
			updatedRowDim = -1;
		}
		
		
		//////////////////////////////////////////////////////////////////////
		// STEP 3: update column dimensions
		///////////////////////////////////////////////////////////////////////
			
		// CASE:  lower == upper --> updated col dim = 1
		if (_colLowerEqualsUpper) 
			updatedColDim = 1;
		
		// CASE: (lower == null && upper == null) --> updated col dim = (cols of input)
		else if (_colLowerBound == null && _colUpperBound == null){
			updatedColDim = this.getOrigDim2(); 
		}
		// CASE: (lower == null) && (upper == constant) --> updated col dim = (constant)
		else if (_colLowerBound == null && isConst_colUpperBound) {
			if (_colUpperBound instanceof IntIdentifier)
				updatedColDim = ((IntIdentifier)_colUpperBound).getValue();
			else if (_colUpperBound instanceof DoubleIdentifier)
				updatedColDim = UtilFunctions.toLong(((DoubleIdentifier)_colUpperBound).getValue());
		}
			
		// CASE: (lower == constant) && (upper == null) && (dimIndex > 0) --> colCount - lower bound + 1
		else if (isConst_colLowerBound && _colUpperBound == null && this.getOrigDim2() >= 0) {
			long colCount = this.getOrigDim2();
			if (_colLowerBound instanceof IntIdentifier)
				updatedColDim = colCount - ((IntIdentifier)_colLowerBound).getValue() + 1;
			else if (_colLowerBound instanceof DoubleIdentifier)
				updatedColDim = UtilFunctions.toLong(colCount - ((DoubleIdentifier)_colLowerBound).getValue() + 1);
		}
		
		// CASE: (lower == constant) && (upper == constant) --> upper bound - lower bound + 1
		else if (isConst_colLowerBound && isConst_colUpperBound) {
			if (_colLowerBound instanceof IntIdentifier && _colUpperBound instanceof IntIdentifier)
				updatedColDim = ((IntIdentifier)_colUpperBound).getValue() - ((IntIdentifier)_colLowerBound).getValue() + 1;
			
			else if (_colLowerBound instanceof DoubleIdentifier && _colUpperBound instanceof DoubleIdentifier)
				updatedColDim = UtilFunctions.toLong( ((DoubleIdentifier)_colUpperBound).getValue() - ((DoubleIdentifier)_colLowerBound).getValue() + 1);
			
			else if (_colLowerBound instanceof IntIdentifier && _colUpperBound instanceof DoubleIdentifier)
				updatedColDim = UtilFunctions.toLong( ((DoubleIdentifier)_colUpperBound).getValue() - ((IntIdentifier)_colLowerBound).getValue() + 1);
			
			else if (_colLowerBound instanceof DoubleIdentifier && _colUpperBound instanceof IntIdentifier)
				updatedColDim = UtilFunctions.toLong( ((IntIdentifier)_colUpperBound).getValue() - ((DoubleIdentifier)_colLowerBound).getValue() + 1);
			
		}
		
		// CASE: column dimension is unknown --> assign -1
		else{ 
			updatedColDim = -1;
		}
		
		return new IndexPair(updatedRowDim, updatedColDim);
		
	}