Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/373.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 用分段函数平滑实验数据_Java_Curve Fitting - Fatal编程技术网

Java 用分段函数平滑实验数据

Java 用分段函数平滑实验数据,java,curve-fitting,Java,Curve Fitting,我有一个单次测量与时间的数据集(大约3000点)。我想通过拟合曲线使数据平滑。这个实验是一个多阶段的物理过程,所以我很确定一个多项式不能适合整个集合 所以我看的是一系列分段多项式。我想指定使用了多少个多项式。在我看来,这似乎是一件相当简单的事情,我希望会有一些预先构建的库来做到这一点。我在ApacheCommonsMath中看到了org.apache.commons.math3.fitting.PolynomialFitter,但它似乎只适用于单个多项式 有人能建议最好的方法吗?首选Java,但

我有一个单次测量与时间的数据集(大约3000点)。我想通过拟合曲线使数据平滑。这个实验是一个多阶段的物理过程,所以我很确定一个多项式不能适合整个集合

所以我看的是一系列分段多项式。我想指定使用了多少个多项式。在我看来,这似乎是一件相当简单的事情,我希望会有一些预先构建的库来做到这一点。我在ApacheCommonsMath中看到了
org.apache.commons.math3.fitting.PolynomialFitter
,但它似乎只适用于单个多项式

有人能建议最好的方法吗?首选Java,但我可以使用Python。

如果您正在寻找,Commons Math将其实现为。最终的结果将是“样条曲线”,即分段三次多项式的平滑序列。

其中有一个名为curve的类,它实现了一些插值方案(线性、样条曲线、akima等)。这些曲线可以将其点作为参数提供给解算器,然后您可以使用全局优化(如Levenberg-Marquardt优化器)来最小化数据到曲线的距离(定义一些首选范数)

这实际上是在“”中完成的,这是数学金融学的一个应用程序。如果曲线中的点(参数)与数据一样多,则可能会得到完美的拟合。如果你的分数比数据少,你会得到最适合你的标准


finmath库中的Levenberg-Marquardt是多线程的,速度非常快(>200个点在一个多项式中拟合)是进行分段插值的良好开端,除非你不能指定边界处的微分。你能澄清一下吗。什么(我想)我想做的是细分时间轴,在每个时间轴中拟合一个低阶多项式,使其连续。据我所知,高阶多项式不适合拟合。因此,您可以将库中对插值的支持应用到每个段,进行一些手动工作,将各部分粘合在一起。您看过了吗?它们是fairly用于曲线拟合的标准分段多项式解决方案。它们通常用于二维情况,但也可以用于一维情况。几乎就是这样,但我想指定时间序列划分为多少部分。如果我将3000个点输入到LoessInterpolator,它会生成2999个多项式函数。我想说,将曲线划分为10,并将最佳多项式拟合到每个部分。(这在原始问题中不清楚,因此我对其进行了编辑)你想让这十个部分平滑地结合在一起吗?我想让它们平滑地结合在一起,但实际上一阶导数可能是不连续的。那么,@PeterHull,你最终是如何得到这十个平滑拟合的多项式的呢?@Michi如果我没记错的话,我开始使用finmath,但不久之后……让我们说我现在正在“另谋职业”很抱歉,我不能再帮你了。我看到finmath仍在积极开发中。这听起来很完美。我会看看finmath-只需要掌握一些金融术语!如果你感兴趣,那么我可以给你发一个小演示-它更独立于应用程序(例如,数学金融).
package net.finmath.tests.marketdata.curves;

import java.text.DecimalFormat;
import java.text.NumberFormat;

import org.junit.Test;

import net.finmath.marketdata.model.curves.Curve;
import net.finmath.marketdata.model.curves.CurveInterface;
import net.finmath.optimizer.LevenbergMarquardt;
import net.finmath.optimizer.SolverException;

/**
 * A short demo on how to use {@link net.finmath.marketdata.model.curves.Curve}.
 * 
 * @author Christian Fries
 */
public class CurveTest {

    private static NumberFormat numberFormat = new DecimalFormat("0.0000");

    /**
     * Run a short demo on how to use {@link net.finmath.marketdata.model.curves.Curve}.
     * 
     * @param args Not used.
     * @throws SolverException Thrown if optimizer fails.
     * @throws CloneNotSupportedException Thrown if curve cannot be cloned for optimization.
     */
    public static void main(String[] args) throws SolverException, CloneNotSupportedException {
        (new CurveTest()).testCurveFitting();
    }

    /**
     * Tests fitting of curve to given data.
     * 
     * @throws SolverException Thrown if optimizer fails.
     * @throws CloneNotSupportedException Thrown if curve cannot be cloned for optimization.
     */
    @Test
    public void testCurveFitting() throws SolverException, CloneNotSupportedException {

        /*
         * Build a curve (initial guess for our fitting problem, defines the times).
         */
        Curve.CurveBuilder curveBuilder = new Curve.CurveBuilder();

        curveBuilder.setInterpolationMethod(Curve.InterpolationMethod.LINEAR);
        curveBuilder.setExtrapolationMethod(Curve.ExtrapolationMethod.LINEAR);
        curveBuilder.setInterpolationEntity(Curve.InterpolationEntity.VALUE);

        // Add some points - which will not be fitted
        curveBuilder.addPoint(-1.0 /* time */, 1.0 /* value */, false /* isParameter */);
        curveBuilder.addPoint( 0.0 /* time */, 1.0 /* value */, false /* isParameter */);

        // Add some points - which will be fitted
        curveBuilder.addPoint( 0.5  /* time */, 2.0 /* value */, true /* isParameter */);
        curveBuilder.addPoint( 0.75 /* time */, 2.0 /* value */, true /* isParameter */);
        curveBuilder.addPoint( 1.0 /* time */, 2.0 /* value */, true /* isParameter */);
        curveBuilder.addPoint( 2.2 /* time */, 2.0 /* value */, true /* isParameter */);
        curveBuilder.addPoint( 3.0 /* time */, 2.0 /* value */, true /* isParameter */);

        final Curve curve = curveBuilder.build();

        /*
         * Create data to which the curve should be fitted to
         */
        final double[] givenTimes   = { 0.0,  0.5, 0.75, 1.0, 1.5, 1.75, 2.5 };
        final double[] givenValues  = { 3.5, 12.3, 13.2, 7.5, 5.5, 2.9,  4.4 };

        /*
         * Find a best fitting curve.
         */

        // Define the objective function
        LevenbergMarquardt optimizer = new LevenbergMarquardt(
                curve.getParameter()    /* initial parameters */,
                givenValues             /* target values */,
                100,                    /* max iterations */
                Runtime.getRuntime().availableProcessors() /* max number of threads */  
                ) {

            @Override
            public void setValues(double[] parameters, double[] values) throws SolverException {

                CurveInterface curveGuess = null;
                try {
                    curveGuess = curve.getCloneForParameter(parameters);
                } catch (CloneNotSupportedException e) {
                    throw new SolverException(e);
                }

                for(int valueIndex=0; valueIndex<values.length; valueIndex++) {
                    values[valueIndex] = curveGuess.getValue(givenTimes[valueIndex]);
                }
            }
        };

        // Fit the curve (find best parameters)
        optimizer.run();

        CurveInterface fittedCurve = curve.getCloneForParameter(optimizer.getBestFitParameters());

        // Print out fitted curve
        for(double time = -2.0; time < 5.0; time += 0.1) {
            System.out.println(numberFormat.format(time) + "\t" + numberFormat.format(fittedCurve.getValue(time)));
        }

        // Check fitted curve
        double errorSum = 0.0;
        for(int pointIndex = 0; pointIndex<givenTimes.length; pointIndex++) {
            errorSum += fittedCurve.getValue(givenTimes[pointIndex]) - givenValues[pointIndex];
        }
        System.out.println("Mean deviation: " + errorSum);

        /*
         * Test: With the given data, the fit cannot over come that at 0.0 we have an error of -2.5.
         * Hence we test if the mean deviation is -2.5 (the optimizer reduces the variance)
         */
        org.junit.Assert.assertTrue(Math.abs(errorSum - -2.5) < 1E-5);
    }
}