Package org.apache.poi.hssf.record.formula.functions

Source Code of org.apache.poi.hssf.record.formula.functions.XYNumericFunction$DoubleArrayPair

/*
* 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.poi.hssf.record.formula.functions;

import org.apache.poi.hssf.record.formula.eval.AreaEval;
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
import org.apache.poi.hssf.record.formula.eval.Eval;
import org.apache.poi.hssf.record.formula.eval.EvaluationException;
import org.apache.poi.hssf.record.formula.eval.NumberEval;
import org.apache.poi.hssf.record.formula.eval.RefEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval;

/**
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
*
*/
public abstract class XYNumericFunction implements Function {
    protected static final int X = 0;
    protected static final int Y = 1;
   
    protected static final class DoubleArrayPair {

    private final double[] _xArray;
    private final double[] _yArray;

    public DoubleArrayPair(double[] xArray, double[] yArray) {
      _xArray = xArray;
      _yArray = yArray;
    }
    public double[] getXArray() {
      return _xArray;
    }
    public double[] getYArray() {
      return _yArray;
    }
    }


    public final Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
      if(args.length != 2) {
        return ErrorEval.VALUE_INVALID;
      }
     
        double[][] values;
    try {
      values = getValues(args[0], args[1]);
    } catch (EvaluationException e) {
      return e.getErrorEval();
    }
        if (values==null
                || values[X] == null || values[Y] == null
                || values[X].length == 0 || values[Y].length == 0
                || values[X].length != values[Y].length) {
            return ErrorEval.VALUE_INVALID;
        }
       
        double d = evaluate(values[X], values[Y]);
        if (Double.isNaN(d) || Double.isInfinite(d)) {
      return ErrorEval.NUM_ERROR;
    }
    return new NumberEval(d);
    }   
    protected abstract double evaluate(double[] xArray, double[] yArray);

    /**
     * Returns a double array that contains values for the numeric cells
     * from among the list of operands. Blanks and Blank equivalent cells
     * are ignored. Error operands or cells containing operands of type
     * that are considered invalid and would result in #VALUE! error in
     * excel cause this function to return null.
     */
    private static double[][] getNumberArray(Eval[] xops, Eval[] yops) throws EvaluationException {
     
      // check for errors first: size mismatch, value errors in x, value errors in y
     
      int nArrayItems = xops.length;
    if(nArrayItems != yops.length) {
        throw new EvaluationException(ErrorEval.NA);
      }
    for (int i = 0; i < xops.length; i++) {
      Eval eval = xops[i];
      if (eval instanceof ErrorEval) {
        throw new EvaluationException((ErrorEval) eval);
      }
    }
    for (int i = 0; i < yops.length; i++) {
      Eval eval = yops[i];
      if (eval instanceof ErrorEval) {
        throw new EvaluationException((ErrorEval) eval);
      }
    }
   
        double[] xResult = new double[nArrayItems];
        double[] yResult = new double[nArrayItems];
     
        int count = 0;
       
    for (int i=0, iSize=nArrayItems; i<iSize; i++) {
        Eval xEval = xops[i];
        Eval yEval = yops[i];
       
        if (isNumberEval(xEval) && isNumberEval(yEval)) {
          xResult[count] = getDoubleValue(xEval);
          yResult[count] = getDoubleValue(yEval);
            if (Double.isNaN(xResult[count]) || Double.isNaN(xResult[count])) {
                throw new EvaluationException(ErrorEval.NUM_ERROR);
            }
            count++;
        }
    }
       
    return new double[][] {
          trimToSize(xResult, count),
            trimToSize(yResult, count),
    };
    }
   
    private static double[][] getValues(Eval argX, Eval argY) throws EvaluationException {
     
      if (argX instanceof ErrorEval) {
      throw new EvaluationException((ErrorEval) argX);
    }
      if (argY instanceof ErrorEval) {
      throw new EvaluationException((ErrorEval) argY);
    }
     
        Eval[] xEvals;
    Eval[] yEvals;
    if (argX instanceof AreaEval) {
        AreaEval ae = (AreaEval) argX;
        xEvals = ae.getValues();
    } else {
        xEvals = new Eval[] { argX, };
    }
   
    if (argY instanceof AreaEval) {
        AreaEval ae = (AreaEval) argY;
        yEvals = ae.getValues();
    } else {
        yEvals = new Eval[] { argY, };
    }
   
    return getNumberArray(xEvals, yEvals);
    }
   
    private static double[] trimToSize(double[] arr, int len) {
        double[] tarr = arr;
        if (arr.length > len) {
            tarr = new double[len];
            System.arraycopy(arr, 0, tarr, 0, len);
        }
        return tarr;
    }
   
    private static boolean isNumberEval(Eval eval) {
        boolean retval = false;
       
        if (eval instanceof NumberEval) {
            retval = true;
        }
        else if (eval instanceof RefEval) {
            RefEval re = (RefEval) eval;
            ValueEval ve = re.getInnerValueEval();
            retval = (ve instanceof NumberEval);
        }
       
        return retval;
    }
   
    private static double getDoubleValue(Eval eval) {
        double retval = 0;
        if (eval instanceof NumberEval) {
            NumberEval ne = (NumberEval) eval;
            retval = ne.getNumberValue();
        }
        else if (eval instanceof RefEval) {
            RefEval re = (RefEval) eval;
            ValueEval ve = re.getInnerValueEval();
                retval = (ve instanceof NumberEval)
                    ? ((NumberEval) ve).getNumberValue()
                    : Double.NaN;
        }
        else if (eval instanceof ErrorEval) {
            retval = Double.NaN;
        }
        return retval;
    }
}
TOP

Related Classes of org.apache.poi.hssf.record.formula.functions.XYNumericFunction$DoubleArrayPair

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.