Apache Commons Math3学习笔记(2) - 多项式曲线拟合(转)

多项式曲线拟合:org.apache.commons.math3.fitting.PolynomialCurveFitter类。

用法示例代码:

 

[java] view plain copy

 
 

  1. // ... 创建并初始化输入数据:  
  2. double[] x = new double[...];  
  3. double[] y = new double[...];  
  4. 将原始的x-y数据序列合成带权重的观察点数据序列:  
  5. WeightedObservedPoints points = new WeightedObservedPoints();  
  6. // 将x-y数据元素调用points.add(x[i], y[i])加入到观察点序列中  
  7. // ...  
  8. PolynomialCurveFitter fitter = PolynomialCurveFitter.create(degree);   // degree 指定多项式阶数  
  9. double[] result = fitter.fit(points.toList());   // 曲线拟合,结果保存于双精度数组中,由常数项至最高次幂系数排列  

 

首先要准备好待拟合的曲线数据x和y,这是两个double数组,然后把这两个数组合并到WeightedObservedPoints对象实例中,可以调用WeightedObservedPoints.add(x[i], y[i])将x和y序列中的数据逐个添加到观察点序列对象中。随后创建PolynomialCurveFitter对象,创建时要指定拟合多项式的阶数,注意阶数要选择适当,不是越高越好,否则拟合误差会很大。最后调用PolynomialCurveFitter的fit方法即可完成多项式曲线拟合,fit方法的参数通过WeightedObservedPoints.toList()获得。拟合结果通过一个double数组返回,按元素顺序依次是常数项、一次项、二次项、……。

完整的演示代码如下:

package fitting;

import org.apache.commons.math3.fitting.PolynomialCurveFitter;
import org.apache.commons.math3.fitting.WeightedObservedPoints;

import java.util.ArrayList;
import java.util.List;

public class TimeCostCalculator {
    public static void main(String[] args) throws Exception {
        TimeCostCalculator tcc = new TimeCostCalculator();
        double timeCost = tcc.calcTimeCost(new CalcCurveFitting());
        System.out.println("--------------------------------------------------------------------------");
        System.out.println("time cost is: " + timeCost + "s");
        System.out.println("--------------------------------------------------------------------------");
    }

    /**
     * 计算指定对象的运行时间开销。
     *
     * @param curveFitting 指定被测对象。
     * @return 返回sub.run的时间开销,单位为s。
     * @throws Exception
     */
    public double calcTimeCost(CurveFitting curveFitting) throws Exception {
        List<Object> params = curveFitting.getParams();
        long startTime = System.nanoTime();
        Object result = curveFitting.run(params);
        long stopTime = System.nanoTime();
        curveFitting.printResult(result);
        System.out.println("start: " + startTime + " / stop: " + stopTime);
        return 1.0e-9 * (stopTime - startTime);
    }

}

interface CurveFitting {
    public List<Object> getParams();

    public Object run(List<Object> params) throws Exception;

    public void printResult(Object result);
}

class CalcCurveFitting implements CurveFitting {

    private WeightedObservedPoints points;

    private final int degree = 5;    // 阶数

    public CalcCurveFitting() {
        int arrayLength = 200000;
        System.out.println(String.format("本算例用于计算多项式曲线拟合。正在初始化计算数据(%s点,%s阶......", arrayLength, degree));
        double[] inputDataX = new double[arrayLength];
        //      inputDataX = new double[] {1, 2, 3, 4, 5, 6, 7};
        double[] inputDataY = new double[inputDataX.length];
        double[] factor = new double[degree + 1];    // N阶多项式会有N+1个系数,其中之一为常数项
        for (int index = 0; index < factor.length; index++) {
            factor[index] = index + 1;
        }
        for (int index = 0; index < inputDataY.length; index++) {
            inputDataX[index] = index * 0.00001;
            inputDataY[index] = calcPoly(inputDataX[index], factor);    // y = sum(x[n) * fact[n])
            // System.out.print(inputDataY[index] + ", ");
        }
        points = new WeightedObservedPoints();
        for (int index = 0; index < inputDataX.length; index++) {
            points.add(inputDataX[index], inputDataY[index]);
        }
        System.out.println("init completely");
    }

    @Override
    public List<Object> getParams() {
        List<Object> params = new ArrayList<Object>();
        params.add(points);
        return params;
    }

    @Override
    public Object run(List<Object> params) throws Exception {
        PolynomialCurveFitter fitter = PolynomialCurveFitter.create(degree);
        WeightedObservedPoints points = (WeightedObservedPoints) params.get(0);
        double[] result = fitter.fit(points.toList());
        return result;
    }

    @Override
    public void printResult(Object result) {
        for (double data : (double[]) result) {
            System.out.println(data);
        }
    }

    private double calcPoly(double x, double[] factor) {
        double y = 0;
        for (int deg = 0; deg < factor.length; deg++) {
            y += Math.pow(x, deg) * factor[deg];
        }
        return y;
    }

}

http://blog.csdn.net/kingfox/article/details/44118319

时间: 2024-10-09 16:44:21

Apache Commons Math3学习笔记(2) - 多项式曲线拟合(转)的相关文章

Commons Collections学习笔记(四)

BeanMap这个Map类用于把一个javaBean转换为Map,在其中存储了javaBean的各个属性的setXXX方法和getXXX方法,属性的类型. public class BeanMap extends AbstractMap implements Cloneable { private transient Object bean;//javaBean对象 private transient HashMap readMethods = new HashMap();//getXXX方法集

Commons Collections学习笔记(三)

这个Map类是基于红黑树构建的,每个树节点有两个域,一个存放节点的Key,一个存放节点的Value,相当于是两棵红黑树,一棵是关于key的 红黑树,一棵是关于Value的红黑树. 关于红黑树的详细介绍,参考<C#与数据结构--树论--红黑树(Red Black Tree)>这篇文章. public final class DoubleOrderedMap extends AbstractMap { private Node[] rootNode = new Node[] { null, nul

Commons Collections学习笔记(二)

public abstract class AbstractBagDecorator extends AbstractCollectionDecorator implements Bag { protected AbstractBagDecorator() { super(); } protected AbstractBagDecorator(Bag bag) { super(bag); } protected Bag getBag() { return (Bag) getCollection(

Commons Collections学习笔记(一)

public interface Bag extends Collection { int getCount(Object object); boolean add(Object object); boolean add(Object object, int nCopies); boolean remove(Object object); boolean remove(Object object, int nCopies); Set uniqueSet(); int size(); boolea

java-框架-apache.commons.*工具

Apache Commons类库 1.1. 开篇 在Java的世界,有很多(成千上万)开源的框架,有成功的,也有不那么成功的,有声名显赫的,也有默默无闻的.在我看来,成功而默默无闻的那些框架值得我们格外的尊敬和关注,Jakarta Commons就是这样的一个框架.如果你至少参与了一个中型规模的Java项目,那么我想有超过一大半的机会你都接触和使用到了Jakarta Commons,不管你自己有没有察觉.就我所知,除了Apache Jakarta其他许多开源框架之外,不少所谓的商业框架其实内部有

apache utils工具类-怎么学习Apache commons utils类

问题描述 怎么学习Apache commons utils类 本人菜鸟一个,最近在看apache commons源码,发现里面有好多好多的工具类啊, 真心佩服大牛们的默默付出,但是太多了,看不过来啊,怎么办?难道全部都要记住么 解决方案 学好英语就可以了,java函数的命名都是英文单词,如果你能理解字面上的意思,不用记忆,你就自动知道了90%的函数的作用.剩下10%,看看文档源码或者google下,也就分分钟搞定. 解决方案二: Apache官网 这个里面有如何使用和快速入门和API 解决方案三

MySQL数据库学习笔记(十二)----开源工具DbUtils的使用(数据库的增删改查)

[正文] 这一周状态不太好,连续打了几天的点滴,所以博客中断了一个星期,现在继续. 我们在之前的几篇文章中学习了JDBC对数据库的增删改查.其实在实际开发中,一般都是使用第三方工具类,但是只有将之前的基础学习好了,在使用开源工具的时才能得心应手.如果对JDBC基础不太清楚,或者对本文看不太懂,建议先回顾一下本人之前的几篇和"MySQL数据库学习笔记"相关的文章.但是不管怎样,今后如果用到了数据库的增删改查,肯定是这篇文章中的代码用的最多. 一.DbUtils简介: DBUtils是ap

spring学习笔记(21)编程式事务配置,service层概念引入

访问数据库事务导入 在我之前的文章<spring学习笔记(19)mysql读写分离后端AOP控制实例>中模拟数据库读写分离的例子,在访问数据库时使用的方法是: public <E> E add(Object object) { return (E) getSessionFactory().openSession().save(object); } 通过直接开启session而后保存对象.查询数据等操作,是没有事务的.而如果我们的项目规模变大,业务逻辑日益复杂,我们在一个方法中进行大

两千行代码的PHP学习笔记汇总_php技巧

本文汇总了PHP学习中常见的各类问题,约有两千多行代码,都是非常实用的技巧.分享给大家供大家参考.具体如下: //语法错误(syntax error)在语法分析阶段,源代码并未被执行,故不会有任何输出. /* [命名规则] */ 常量名 类常量建议全大写,单词间用下划线分隔 // MIN_WIDTH 变量名建议用下划线方式分隔 // $var_name 函数名建议用驼峰命名法 // varName 定界符建议全大写 // <<<DING, <<<'DING' 文件名建议