package org.simantics.spreadsheet.graph.formula; import org.simantics.spreadsheet.graph.CellFormulaFunction; import org.simantics.spreadsheet.graph.CellValueVisitor; import org.simantics.spreadsheet.graph.SpreadsheetGraphUtils; import org.simantics.spreadsheet.graph.SpreadsheetMatrix; import org.simantics.spreadsheet.graph.parser.ast.AstArgList; import org.simantics.spreadsheet.graph.parser.ast.AstValue; public class GeomeanFormulaFunction implements CellFormulaFunction { @Override public Object evaluate(CellValueVisitor visitor, AstArgList args) { if (args.values.size() == 0) throw new IllegalStateException(); double result = 1.0; double count = 0.0; for (AstValue value : args.values){ Object r = value.accept(visitor); if (r instanceof SpreadsheetMatrix) { Object v = ((SpreadsheetMatrix) r).productWithFormulaError(); if(v instanceof String) return v; double dval = ((Number)v).doubleValue(); if(dval!=0.0){ result = result*dval; count += ((SpreadsheetMatrix) r).countOfActualDoubleValues(); } } else { FormulaError2 error = FormulaError2.forObject(r); if(error!=null) return error.getString(); Number vNum = SpreadsheetGraphUtils.asValidNumber(r); Double v = null; if(vNum!=null) v = vNum.doubleValue(); if(v!=null){ if(v<=0) return FormulaError2.NUM.getString(); result = result*v; count++; } } } if(result==0.0 || count==0.0) return FormulaError2.NUM.getString(); return Double.valueOf(Math.pow(result, (1.0/count))); } }