/** * (C) Copyright IBM Corp. 2010, 2015 * * Licensed 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 com.ibm.bi.dml.udf.lib; import com.ibm.bi.dml.udf.FunctionParameter; import com.ibm.bi.dml.udf.Matrix; import com.ibm.bi.dml.udf.PackageFunction; import com.ibm.bi.dml.udf.PackageRuntimeException; import com.ibm.bi.dml.udf.Scalar; import com.ibm.bi.dml.udf.Matrix.ValueType; import com.ibm.bi.dml.udf.Scalar.ScalarValueType; /** * Wrapper class for binning a sorted input vector * */ public class BinningWrapper extends PackageFunction { private static final long serialVersionUID = 1L; private static final String OUTPUT_FILE = "TMP"; //return matrix private Matrix _bins; //return matrix col_bins private Scalar _defBins; //return num defined bins @Override public int getNumFunctionOutputs() { return 2; } @Override public FunctionParameter getFunctionOutput(int pos) { switch(pos) { case 0: return _bins; case 1: return _defBins; } throw new PackageRuntimeException("Invalid function output being requested"); } @Override public void execute() { try { //get input parameters (input matrix assumed to be sorted) Matrix inM = (Matrix) getFunctionInput(0); double [][] col = inM.getMatrixAsDoubleArray(); int binsize = Integer.parseInt(((Scalar)getFunctionInput(1)).getValue()); int numbins = Integer.parseInt(((Scalar)getFunctionInput(2)).getValue()); int nrowX = (int) inM.getNumRows(); //execute binning (extend bins for duplicates) double[] col_bins = new double[numbins+1]; int pos_col = 0; int bin_id = 0; col_bins[0] = col[0][0]; while(pos_col < nrowX-1 && bin_id < numbins) { //for all bins pos_col = (pos_col + binsize >= nrowX) ? nrowX-1 : pos_col + binsize; double end_val = col[pos_col][0]; col_bins[bin_id+1] = end_val; //pull all duplicates in current bin boolean cont = true; while( cont && pos_col < nrowX-1 ){ if( end_val == col[pos_col+1][0] ) pos_col++; else cont = false; } bin_id++; } //prepare results int num_bins_defined = bin_id; for( int i=0; i<num_bins_defined; i++ ) col_bins[i] = (col_bins[i] + col_bins[i+1])/2; //create and copy output matrix String dir = createOutputFilePathAndName( OUTPUT_FILE ); _bins = new Matrix( dir, col_bins.length, 1, ValueType.Double ); _bins.setMatrixDoubleArray(col_bins); _defBins = new Scalar(ScalarValueType.Integer, String.valueOf(num_bins_defined)); } catch (Exception e) { throw new PackageRuntimeException("Error executing external order function", e); } } }