blob: fc44ed1075702da4a6e3f3f7678a10d172dc20d2 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.sysds.runtime.functionobjects;
import org.apache.sysds.runtime.DMLRuntimeException;
import org.apache.sysds.runtime.matrix.data.CTableMap;
import org.apache.sysds.runtime.matrix.data.MatrixBlock;
import org.apache.sysds.runtime.matrix.data.MatrixIndexes;
import org.apache.sysds.runtime.matrix.data.Pair;
import org.apache.sysds.runtime.util.UtilFunctions;
public class CTable extends ValueFunction
{
private static final long serialVersionUID = -5374880447194177236L;
private static CTable singleObj = null;
private CTable() {
// nothing to do here
}
public static CTable getCTableFnObject() {
if ( singleObj == null )
singleObj = new CTable();
return singleObj;
}
public void execute(double v1, double v2, double w, boolean ignoreZeros, CTableMap resultMap, MatrixBlock resultBlock) {
if( resultBlock != null )
execute(v1, v2, w, ignoreZeros, resultBlock);
else
execute(v1, v2, w, ignoreZeros, resultMap);
}
public void execute(double v1, double v2, double w, boolean ignoreZeros, CTableMap resultMap) {
// If any of the values are NaN (i.e., missing) then
// we skip this tuple, proceed to the next tuple
if ( Double.isNaN(v1) || Double.isNaN(v2) || Double.isNaN(w) ) {
return;
}
// safe casts to long for consistent behavior with indexing
long row = UtilFunctions.toLong( v1 );
long col = UtilFunctions.toLong( v2 );
// skip this entry as it does not fall within specified output dimensions
if( ignoreZeros && row == 0 && col == 0 ) {
return;
}
//check for incorrect ctable inputs
if( row <= 0 || col <= 0 ) {
throw new DMLRuntimeException("Erroneous input while computing the contingency table (one of the value <= zero): "+v1+" "+v2);
}
//hash group-by for core ctable computation
resultMap.aggregate(row, col, w);
}
public void execute(double v1, double v2, double w, boolean ignoreZeros, MatrixBlock ctableResult)
{
// If any of the values are NaN (i.e., missing) then
// we skip this tuple, proceed to the next tuple
if ( Double.isNaN(v1) || Double.isNaN(v2) || Double.isNaN(w) ) {
return;
}
// safe casts to long for consistent behavior with indexing
long row = UtilFunctions.toLong( v1 );
long col = UtilFunctions.toLong( v2 );
// skip this entry as it does not fall within specified output dimensions
if( ignoreZeros && row == 0 && col == 0 ) {
return;
}
//check for incorrect ctable inputs
if( row <= 0 || col <= 0 ) {
throw new DMLRuntimeException("Erroneous input while computing the contingency table (one of the value <= zero): "+v1+" "+v2);
}
// skip this entry as it does not fall within specified output dimensions
if( row > ctableResult.getNumRows() || col > ctableResult.getNumColumns() ) {
return;
}
//add value
ctableResult.quickSetValue((int)row-1, (int)col-1,
ctableResult.quickGetValue((int)row-1, (int)col-1) + w);
}
public int execute(int row, double v2, double w, int maxCol, MatrixBlock ctableResult)
{
// If any of the values are NaN (i.e., missing) then
// we skip this tuple, proceed to the next tuple
if ( Double.isNaN(v2) || Double.isNaN(w) ) {
return maxCol;
}
// safe casts to long for consistent behavior with indexing
int col = UtilFunctions.toInt( v2 );
if( col <= 0 ) {
throw new DMLRuntimeException("Erroneous input while computing the contingency table (value <= zero): "+v2);
}
//set weight as value (expand is guaranteed to address different cells)
ctableResult.quickSetValue(row-1, col-1, w);
//maintain max seen col
return Math.max(maxCol, col);
}
public Pair<MatrixIndexes,Double> execute( long row, double v2, double w )
{
// If any of the values are NaN (i.e., missing) then
// we skip this tuple, proceed to the next tuple
if ( Double.isNaN(v2) || Double.isNaN(w) )
return new Pair<>(new MatrixIndexes(-1,-1), w);
// safe casts to long for consistent behavior with indexing
long col = UtilFunctions.toLong( v2 );
if( col <= 0 )
throw new DMLRuntimeException("Erroneous input while computing the contingency table (value <= zero): "+v2);
return new Pair<>(new MatrixIndexes(row, col), w);
}
}