package org.matheclipse.core.reflection.system;

import org.apache.commons.math3.optimization.fitting.PolynomialFitter;
import org.apache.commons.math3.optimization.general.LevenbergMarquardtOptimizer;
import org.matheclipse.core.convert.Convert;
import org.matheclipse.core.eval.exception.Validate;
import org.matheclipse.core.eval.interfaces.AbstractFunctionEvaluator;
import org.matheclipse.core.interfaces.IAST;
import org.matheclipse.core.interfaces.IExpr;
import org.matheclipse.core.interfaces.ISignedNumber;
import org.matheclipse.core.interfaces.ISymbol;

/**
 * Polynomial fitting of a given data point set.
 * 
 * 

* Syntax: Fit[ data, degree, variable ] *

* * * Examples:
* Fit[{{1,1},{2,4},{3,9},{4,16}},2,x] gives x^2.0
* Fit[{1,4,9,16},2,x] gives x^2.0 * *

* See Levenberg–Marquardt algorithm *

*/ public class Fit extends AbstractFunctionEvaluator { public Fit() { super(); } @Override public IExpr evaluate(final IAST ast) { // switch to numeric calculation return numericEval(ast); } @Override public IExpr numericEval(final IAST ast) { Validate.checkSize(ast, 4); if (ast.arg2().isSignedNumber() && ast.get(3).isSymbol()) { int rowSize = -1; int degree = ((ISignedNumber) ast.arg2()).toInt(); PolynomialFitter fitter = new PolynomialFitter(degree, new LevenbergMarquardtOptimizer()); int[] im = ast.arg1().isMatrix(); if (im != null && im[1] == 2) { IAST matrix = (IAST) ast.arg1(); IAST row; for (int i = 1; i < matrix.size(); i++) { row = matrix.getAST(i); fitter.addObservedPoint(1.0, ((ISignedNumber) row.arg1()).doubleValue(), ((ISignedNumber) row.arg2()).doubleValue()); } } else { rowSize = ast.arg1().isVector(); if (rowSize < 0) { return null; } IAST vector = (IAST) ast.arg1(); for (int i = 1; i < vector.size(); i++) { fitter.addObservedPoint(1.0, i, ((ISignedNumber) vector.get(i)).doubleValue()); } } return Convert.polynomialFunction2Expr(fitter.fit(), (ISymbol) ast.get(3)); } return null; } }

Ads help maintain this website.