]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.spreadsheet.graph/src/org/simantics/spreadsheet/graph/formula/GeomeanFormulaFunction.java
SpreadsheetCells with Circular References support iterations.
[simantics/platform.git] / bundles / org.simantics.spreadsheet.graph / src / org / simantics / spreadsheet / graph / formula / GeomeanFormulaFunction.java
1 package org.simantics.spreadsheet.graph.formula;\r
2 \r
3 import org.simantics.spreadsheet.graph.CellFormulaFunction;\r
4 import org.simantics.spreadsheet.graph.CellValueVisitor;\r
5 import org.simantics.spreadsheet.graph.SpreadsheetGraphUtils;\r
6 import org.simantics.spreadsheet.graph.SpreadsheetMatrix;\r
7 import org.simantics.spreadsheet.graph.parser.ast.AstArgList;\r
8 import org.simantics.spreadsheet.graph.parser.ast.AstValue;\r
9 \r
10 public class GeomeanFormulaFunction implements CellFormulaFunction<Object> {\r
11 \r
12     @Override\r
13     public Object evaluate(CellValueVisitor visitor, AstArgList args) {\r
14         if (args.values.size() == 0)\r
15             throw new IllegalStateException();\r
16         double result = 1.0;\r
17         double count = 0.0;\r
18         for (AstValue value : args.values){\r
19                 Object r = value.accept(visitor);\r
20                 if (r instanceof SpreadsheetMatrix) {\r
21               Object v = ((SpreadsheetMatrix) r).productWithFormulaError();\r
22               if(v instanceof String) return v;\r
23               double dval = ((Number)v).doubleValue();\r
24               if(dval!=0.0){\r
25                   result = result*dval;\r
26                   count += ((SpreadsheetMatrix) r).countOfActualDoubleValues();\r
27               }\r
28                 } else {\r
29                                 FormulaError2 error = FormulaError2.forObject(r);\r
30                                 if(error!=null) return error.getString();\r
31                         \r
32                                 Number vNum = SpreadsheetGraphUtils.asValidNumber(r);\r
33                                 Double v = null;\r
34                                 if(vNum!=null) v = vNum.doubleValue();\r
35                                 \r
36                         if(v!=null){\r
37                                 if(v<=0) return FormulaError2.NUM.getString();\r
38                                 result = result*v;\r
39                                 count++;\r
40                         }\r
41                 }\r
42         }\r
43         if(result==0.0 || count==0.0) return FormulaError2.NUM.getString();\r
44         return Double.valueOf(Math.pow(result, (1.0/count)));\r
45     }\r
46 \r
47 }\r