图片缩略图

形状语言建模

版本1.14 (668 KB) 约翰D 'Errico
使用形状基元的最小二乘样条建模

141下载

更新2017年4月16日

查看版本历史

查看许可协议

如果您只能在荒岛上的笔记本电脑上下载一个曲线拟合工具,那么应该就是这个了。
多年来,我一直建议人们使用最小二乘样条进行曲线拟合,但有一个警告。样条曲线提供了极大的灵活性来构建任何形状或形式的曲线。它们几乎可以很好地适应你扔给它们的任何一组数据。这种灵活性有时也是他们的缺点。像多项式模型一样,如果你不小心的话,样条曲线也可能过于灵活。诀窍是将你对所研究系统的知识应用到问题中。
作为科学家、工程师、数据分析师等,您通常对希望建模的过程有一定的了解。有时这些知识来自物理原理,有时来自经验,有时这些知识只是来自于观察数据图。不管来源是什么,我们经常想要在我们的建模工作中构建这个过程的先验知识。这可能是使用非线性回归工具的最大原因,我认为也是最糟糕的原因。如果您拟合数据的s型函数只是因为它碰巧是单调的,并且您的数据似乎具有该属性,那么您已经做出了错误的建模工具选择。(如果你正在拟合一个s型曲线,因为这是已知的适合你的过程的模型,然后继续拟合s型曲线。)
当你只需要一个单调曲线的拟合时,我认为合适的工具是最小二乘样条,但是这种样条被适当地约束在你所知道的基本形状上。这是一种非常贝叶斯的建模方法,在我的经验中非常有用。
这里提供的SLM工具为您提供了一个易于使用的界面,可以根据数据构建无限数量的曲线类型。SLM代表形状语言建模。其思想是使用一组形状原语为曲线拟合提供一个处方。如果您的曲线是单调的,那么将该信息构建到模型中,这样您就可以估计最适合您的数据的单调曲线。你会发现,一旦你采用了合适的约束条件,你就会想知道为什么过去要使用非线性回归!!
例如,该文件的截图是由以下数据生成的:

X = (sort(rand(1,100)) - 0.5)*pi;
Y = sin(x)^5 + randn(size(x))/10;

slm = slmengine (x, y,“阴谋”,“对”,“结”,10日,“增加”,“对”,…
“leftslope”,0,' rightslope ', 0)
slm =
形式:“slm”
度:3
绳结:[10x1双]
系数:[10x2 double]
处方:[1x1 struct]
X: [100x1倍]
Y: [100x1倍]

你可以用采样法计算样条曲线或它的导数。

slm slmeval (1.3)
ans =
0.79491

使用plotslm绘制这些样条曲线。

plotslm (slm)

plotslm函数很好,因为它是一个简单的图形用户界面,允许你绘制曲线,残差,它的导数或积分。您还可以评估样条的各种参数,例如在一个区间内的最大函数值,最小或最大斜率等。

slmpar (slm maxslope)
ans =
1.5481

您可以使用属性/值对接口向slmengine提供所有这些信息。Slmset调解这种交互,因此您可以使用它来创建将要使用的属性集。默认的属性集及其值由slmset给出。关于函数的形状、斜率、曲率、值等一切都可以通过一个简单的命令来控制。SLMENGINE还提供生成各种阶样条的能力,以及自由结样条。

有关实际使用的SLM工具的完整示例集,请参阅本提交文件附带的已发布教程。还有一个小论文包括形状语言建模曲线拟合的概念。

在将来的某个时候,SLM工具包将得到相当大的改进。我将添加一个图形界面。同样,如果我错过了任何自然形状原语,请让我知道。虽然我努力做到包容,但我肯定错过了一些东西。如果我能把你最喜欢的添加到上面的列表中,我会尽量这样做。

最后,SLM工具需要优化工具箱来解决各种估计问题。

引用作为

John D'Errico(2021)。形状语言建模(//www.tatmou.com/matlabcentral/fileexchange/24443-slm-shape-language-modeling), MATLAB中央文件交换。检索

评论及评分(210

涛阮

杰夫生气

在R2020b为我工作。SLM可能是我从File Exchange获得的最有用的工具箱。

•Farno

Add on不适用于R2020b。

马可洛摩纳哥

SLM发动机是否能够自动检测最佳结位置,而无需用户提供一套?

Kassandra科斯塔

嗨,约翰,
谢谢你的工具箱!它完成了我一直在寻找的数据分析。我的一个问题是,是否有一种方法可以将不确定性纳入数据集的y值?我想找到在y值上有较大误差(±20%)的统计上显着的断点。谢谢你的帮助。

Yunliang气

莎拉

你好,
我有一个不同系统退化的数据集。正常情况下,当系统的健康度达到初始值的80%时,系统就会降级。
然而,由于时间限制,其中许多系统尚未达到80%。
我的问题是,我如何使用你的工具箱来推断我的数据,直到它们达到80%。
谢谢你的帮助

埃德加·格瓦拉

优秀的工具箱,真的很容易使用,并提供了大量的例子

默罕默德阿里

亲爱的约翰,

这是一个了不起的工具,我喜欢它。

我用它来拟合一个分段线性模型,该模型具有预定义的结点(来自聚类算法),具有一个因变量和一个自变量。

我对你的工具如何在结点处加强位置连续性(C0)很感兴趣。我的意思是你对最小二乘误差优化问题施加了什么样的约束或公式。我注意到您使用了Hermit函数,但我不知道这是否与节点上的连续性强制相关。

提前感谢并保持惊人的工作。

马克斯Torbenson

一个RJ

伟大的工具!然而,我没有设法执行分段线性拟合约束的斜率。假设我想要拟合3段时间序列数据并限制中间段的斜率小于0,第一个和最后一个斜率不受约束。断点将由SLM确定。如何在SLM中做到这一点?谢谢你!

俯视Grine

Seb斯波恩

豪尔赫·席尔瓦

蓝丽宇

夏朗Magavi

女士七

Zakarya Motea

乔·所罗门

出色的,非常有用的曲线拟合工具箱,拥有许多有用的功能,没有Matlab的曲线拟合工具箱。我希望看到这扩展到3D表面拟合。

dfsfsddfs

哈利的绿

绝对优秀的工具和易于使用。如果有选择获得最佳结位置周围的置信区间与自由内部结的模型会很好吗

Diana-Patricia Danciu

ZhiH

亲爱的约翰,
感谢这个有用的工具,但是我仍然不能通过使用下面的这些代码获得我的振荡数据的光滑包络曲线。

[up_x, up_y] = slmengine (x, y,“env”、“一口”,“情节”,“关闭”,“结”,60);
[dw, dw_x dw_y] = slmengine (x, y,“env”,“正”,“情节”,“关闭”,“结”,50);
人物,情节(x, y, up_y; dw_y]);

问题详情见:https://ww2.mathworks.cn/matlabcentral/answers/413510-plot-a-smooth-envelope-for-oscillation-curves

你能帮帮我吗?

Arezoo GeramiPour

G Ls

穆罕默德Mousaviraad

sundar

嗨,约翰,是否可以将这个函数用于3D中的一组点?

Xueying陆

感谢这个有用的工具,但是我有一个问题:当我使用slm2pp并尝试恢复pp的函数形式(并绘制它)时,它们看起来与原始数据不一样(非常不同)。你知道为什么是这样的情况下,我怎么能得到一个适合数据的pp函数形式吗?

Eric Landahl

Joton

约翰,谢谢你给我这么好的工具,帮了我很多忙!
我想在一个循环中使用plotslm绘制很多图形,并将这些图形保存到特定的文件夹(png格式)。但我无法使用matlab saveas功能来工作。我还想隐藏图形图,因为我只想在文件夹中查看它们,而不是在循环期间弹出它们。
matlab命令集(0,'DefaultFigureVisible','off');似乎不影响剧情

有什么办法吗?

泰德Langhorst

萨尔

莫特Turkol

莫特Turkol

亲爱的约翰,
首先,我想说,这确实是一个非常强大和有用的工具。非常感谢你的分享。在我的研究中,我有时会遇到实验中记录为位移的重复值,并且我知道位移值应该在什么范围内。我尝试测试SLM以拟合三次样条,其值将在使用工具的“errorbar”属性的训练输入点保持在测量精度范围内。有一些情况会失败,除非我将“errorbar”设置为默认值“[]”,但是当我使用slmeval来检查拟合函数是否留在我预期的测量误差范围内时,它确实是这样做的。这对我来说似乎很奇怪,因为有一个函数可以在使用默认选项的错误界限内适合,但当我使用“errorbar”属性显式定义上述界限时,即使所有其他属性完全相同,它也无法这样做。我尝试改变“正则化”属性,以及将其设置为“平滑”,但无济于事。
我的“errorbar”属性向量用“errbar”变量定义,看起来像这样:[0;0.000226717384185;0.000226717384185;0]。这里的值“0.000226717384185”对应于我所说的tick-precision。这应该对应于左端和右端点值被设置为定义为训练输入的精确y值,而内部点被期望位于+- tick-precision范围内的情况。下面我将提供我使用属性对值设置的约束配方,其中“caseTimes”是训练输入x值,而“caseDisps”是训练y值。假设均匀间隔的结的数量被设置为像“totPts-totReps”这样的值,通常对应于3或4,这取决于我评估的情况。拟合函数的预期行为应该是一条向下凹的曲线:
slm = slmengine(caseTimes, caseDisps,…)
'knots', (totps - totreps),…
'errorbar', errbar,…
'concavedown', 'on',…
“endconditions”、“notaknot”);

这无法拟合所需的函数,并给出以下警告:LSQLIN没有找到可行的解决方案。这可能反映了不一致的处方集。
现在,我将“errorbar”属性设置为默认值(没有定义error-bar),并设置“leftvalue”-“rightvalue”属性,如下所示:
slm = slmengine(caseTimes, caseDisps,…)
'knots', (totps - totreps),…
'errorbar',[],…
'leftvalue',caseDisps(1), 'rightvalue',caseDisps(end),…
'concavedown', 'on',…
“endconditions”、“notaknot”);

上面的一组属性工作得很好,用下面的语句进行验证,以检查函数值是否在我的“tickPrecision”变量定义的错误范围内:
>> all(abs(slmeval(caseTimes, slm) - caseDisps)) < tickPrecision
ans =

1

我应该重复一下,我使用了“regularization”参数,同时将“errorbar”属性设置为我在这篇文章之前定义的向量,但无法获得我使用默认[]值所获得的工作结果。正如您所看到的,每个其他属性值对都是完全相同的。我无法理解为什么显式设置的“errorbar”属性不工作,即使它对应于工作案例的一组属性。你能帮忙找出可能出了什么问题吗?

感谢您在百忙之中抽出时间来阅读!

哥特克鲁格

非常感谢!

HiWave

苏西阿曼

此外,在拟合时约束导数或正常值为真的方法是什么?

苏西阿曼

这个有3d版本吗?

约翰D 'Errico

@Carrington Metts

您可以在调用工具之前记录x数据。这将变换问题,就好像你用了一个log x轴。

约翰D 'Errico

@Kevin程:

理论?本质上它只是一个线性回归样条。再加上一个小的惩罚用二阶导数的平方使样条正则化。这部分来自基本的平滑样条理论。你可以用一些简单的方法来改变正则化,但是没有什么特别的。

最后,我允许用户应用任何一组约束,这些约束是关于曲线基本形状的规定。这是我多年前开发的一个创新。所有这些规定都可以通过样条代码转换为对样条参数的约束。因此单调性,曲率约束,迫使样条通过一个点等。所有这些都被简单地写成对样条参数的线性约束。不同之处在于,用户不需要制定所需的实际方程,这正是SLM的价值所在,因为这些方程的编写可能相当复杂。我已经帮你做了最辛苦的工作。

我不能提供任何关于这些想法的论文,因为我从来没有写过。

郑嘉颖

谢谢,这真的很有帮助。但是,这个项目背后的理论是什么呢?

RB

卡灵顿Metts

感谢您提供的优秀工具包!只有一个问题——在设置结点和样条之前,有可能改变数据的轴吗?我试图将一个线性分段函数拟合到一组具有对数轴的数据中,但我不知道如何使用slmengine来做到这一点。
谢谢,
卡灵顿

斯科特·奥特森

嗨,约翰,

谢谢你的回答。是的,我已经使用了单调性约束,但在实际数据中,二阶导数没有(可知的)约束。因此,就目前情况而言,我偶尔会出现数值误差,而且收敛速度经常很慢。

这就是我问惩罚样条的原因。无约束惩罚样条算法具有数值鲁棒性、训练速度快、易于编码等特点。也有单调性约束的版本(我提到的Pya论文),但它们没有办法约束端点的值。

我认为我可以修改SLM工具箱来实现带端点约束的pya,但是我不能完全理解SLM代码是如何工作的。

那么,有没有可能添加惩罚约束样条呢?或者,是否有文档描述了现有代码的内部工作?

谢谢,

斯科特

杰克

嗨。

首先,感谢您提供的实用工具箱。我如何在自由模式下指定节之间的最小距离?我的问题有一些限制。结点之间至少要有3个数据点。

谢谢。

哈米德amini

slmengine中的错字。M,第1012-1017行?

---------------------------------------------------------
%左侧最大值
如果~ isempty (prescription.LeftMaxValue)
M = 0 (1,nc);
M(1) = 1;
Mineq = [Mineq;M];
rhsineq = [rhsineq;prescription.LeftMinValue];
结束
----------------------------------------------------------

应该是:

---------------------------------------------------------
%左侧最大值
如果~ isempty (prescription.LeftMaxValue)
M = 0 (1,nc);
M(1) = 1;
Mineq = [Mineq;M];
rhsineq = [rhsineq;prescription.LeftMaxValue];
结束
----------------------------------------------------------

约翰D 'Errico

看起来我并没有收到评论的通知。对不起。

@Emanuele -不,一般的不等式约束不能被支持。金宝app这通常会很困难,因为你描述的约束条件对应于曲线上每一点的不等式。因此,即使使用fmincon,也不可能实现。至多,我们可以实现一个必要的约束,即它必须在某个点的样本集上得到满足。但是,即使您在一些大的样本点集上执行该要求,它仍然可能在中间的某个位置失败。

单调性确实是你所描述的一般类的约束。但在这里,我可以使用Fritsch & Carlson的结果,使我能够以易于书写的形式在样条上创建充分条件。

@Scott -如果可能的话,一个好的方法是应用单调性约束,或者可能是一个以凹性形式的二阶导数的全局约束。这些约束对曲线的形状有巨大的规则性影响,排除了可能发生的糟糕情况。

Mallik Gurram

杰夫·斯坦利

斯科特·奥特森

我在使用SLM工具箱时运气不错,除了一种问题。我拟合的大部分曲线都是平滑的,几乎是平坦的,有些部分的导数很高,而高导数的位置是不可预测的。所以我需要在每个地方打很多结。

在这种情况下,我有时会在SLM装配过程中出现不适,自动选择结也不起作用。

另一方面,如果我使用粗糙度惩罚样条来拟合曲线,我可以使用很多结点(比如100个),并且永远不会发生不良调节。但是我没有SLM的固定端点和单调性约束。

基本且易于实现的无约束惩罚样条算法如下:

《Wiley跨学科评论:计算统计》,John Wiley & Sons出版社,2010年第2期,637-653页

在这里:

Kagerer, K.样条曲线在最小二乘回归分析中的应用

并且,这里有一个具有单调性但没有端点约束的算法:

杨建军,杨建军。形状约束加性模型的建模与计算,计算机工程学报,2015,25 (5):543-559

我考虑修改SLM以实现Pya算法,然后添加端点约束。但我看过SLM代码,不太了解现有的算法。

那么,在SLM中加入粗糙度惩罚拟合算法是否可行呢?

埃Cattarinuzzi

亲爱的约翰,
最近我用SLM来拟合一些有噪声的数据。我发现它很有帮助,因此,非常感谢你的贡献。
我想知道用户可以给出的处方:人们可以单独规定y及其导数(yp, ypp, yppp)的约束条件;假设一个人对曲率导数的符号有一些了解,他可能想要规定一个不等式涉及这些导数的非线性组合,例如,

Yppp - (3*yp*ypp^2)/(1 + yp^2) >(或<)0

这样的约束不能在由slmengine组装的约束矩阵M中形式化(我错了吗?)
你认为设置这样的非线性不等式约束可以通过nonlinconstr()和fmincon()结合使用来解决吗?
由于slmengine已经使用fmincon()当' internorknots '被设置为'free',我想知道非线性不等式约束是否可以类似地接近。

-埃

龙川李

这是我见过的最好的工具箱之一!

约翰D 'Errico

很抱歉,存储样条曲线的方法有很多种。你显然期待其他形式。

SLM = slmengine(0:10,rand(1,11));
bspl = fn2fm(slm2pp(slm),'B-');

bspl
bspl =
形式:“B -”
结:[0 0 0 0 2 4 6 8 10 10 10 10 10]
系数:[0.27526 0.069372 0.71806 0.8488 -0.063009 0.7445 -0.04073 0.71297]
数量:8
秩序:4
昏暗的:1

我给您的代码是您所要求的,它是使用Mathworks提供的代码将样条曲线转换为b样条曲线的代码。

他们选择了如何表示b样条。

如果你在那件事上需要帮助,你得去找他们。

医生fn2fm

如果你想要其他形式的系数,就像我说的,去找TMW。

rowJoe

亲爱的约翰,

非常感谢您2016年5月9日的帖子。

在此期间,我跟踪了你的帖子,但没有成功。如果我在处理b样条,我会期待一个基展开系统(由Ramsay在这里描述):http://www.psych.mcgill.ca/misc/fda/ex-basis-a1.html
如果我定义一个有n个函数的基展开系统我就会得到一个n乘以n个系数的矩阵。

在你的例子中(用b样条形式),我得到一个包含系数的1x8矩阵。

别误会我。你的工具真是太棒了。这就是为什么我尝试在Ramsay的功能数据分析工具箱(可下载R和Matlab下)中导入结果(使用您的工具创建)www.functionaldata.org免费)。

我想尝试一下:
-用工具箱将数据拟合为b样条。所以我计算了系数矩阵(在你的例子中:bspll .coefs)。
—导入fda工具中的系数矩阵。
-用fda工具箱分析曲线。

也许您或其他用户有一些解决这个问题的想法。
我会很高兴的。

——乔纳斯

p.s.:如果有人需要一个例子,我张贴了我最小的情况在这里:http://de.mathworks.com/matlabcentral/answers/293307-optimize-b-spline-fitting-while-working-with-functional-data-analysis-fda-and-slm-toolbox

茱莉亚豪

伟大的工具!

我最近从2014年更新到2015b,现在运行任何SLM工具都会导致MATLAB崩溃。

还有其他人遇到过这个问题吗?或者知道为什么会这样吗?我想也许是从我的旧电脑上传输文件可能与此有关-但即使重新下载似乎也无济于事。

茱莉亚

约翰D 'Errico

@Jorge -

没有看到你的数据,我只能猜测发生了什么。

您指定了两条信息,即增加和降低。所以曲线一定是递增的,很可能是上渐近线。

如果存在线性分段,则表明存在数据似乎指示不同的区域,但曲线的行为受到约束。在这些线段中,线段简化为退化的三次多项式,也就是线性线段。

也就是说,问题中所有的线段都是三次的。但有些线段可能是退化立方的。线段就是这样。

也许这些数据相当嘈杂。或者也许你有更多的结比数据充分支持,特别是在结的数量上下文中。金宝app

一个解决方案是使用更少的结。当然,这就降低了曲线的灵活性,从而降低了拟合可能带有噪声的数据的自由度。

第二个解决方案是指定正则化参数“regularization”。这将使你的曲线更平滑。该参数的默认值为0.0001。所以尝试一个更大的值。(这里的值太大会导致曲线接近于数据的直线。)

另一种选择(会慢一点,因为它会利用交叉验证选项)是将“regularization”属性指定为“crossvalidation”。这将自动选择似乎由数据指示的正则化程度。正如我所说的,这将是一个计算更密集的解决方案,但它通常会导致更令人满意的拟合。

约翰D 'Errico

他们改变了脚下的一切。:)

所以在我最近的版本中,我修复了这个问题,但也增加了名为“FminconAlgorithm”和“LsqlinAlgorithm”的选项。我想我得发布一下。

斯科特·奥特森

这对我的测试问题很有效,例如:

SLM = slmengine(x,y,'knots',10,' increase ','on','leftminvalue', 0,' rightmaxvalue', 1);

但是有一个Matlab优化工具箱警告:

警告:选项LargeScale = 'off'和算法= 'trust-region-reflective'冲突。忽略算法和
运行active-set算法。这些设置将在将来的版本中出现错误。
>在sql中(第297行)
在slmengine>中solve_slm_system(第2490行)
在slmengine>中,slmengine_cubic(第2332行)
在slmengine中(第255行)

警告消失了,如果我设置选项,事情仍然可以工作。算法='active-set'之后,在slmengine中关闭了大规模。M线2486。

这会破坏其他东西吗?我正在运行Matlab R2015b。

Jorge Yannie

你好约翰,

我有一个位移与时间的数据,我试图将“增加”和“向下凹”的曲线拟合到我的数据集(减速双曲线类型的行为)。所得到的曲线是线性段和三次样条的组合。我知道导数应该随时间减小而不是线性线段给出的常数。

是否有一种方法可以关闭线性拟合并迫使slm只拟合样条?

非常感谢!

约翰D 'Errico

@rowJoe

你要的是短的。

SLM = slmengine(0:10,rand(1,11));
bspl = fn2fm(slm2pp(slm),'B-');

它应该是b样条形式。

rowJoe

太棒了,约翰。我想用你的工具箱用b样条进行功能数据聚类。是否有机会从(b?)样条得到基展开?

如果你能对我的问题提供一个简短的回答,那就太好了。

约翰D 'Errico

Leandro -万一你想计算一个高阶的Hermite插值。虽然slmeval目前不能处理比cubic更高阶的表单,但可以使用ppval或fnval等工具来处理。

这里有一个例子,我创建了一个高阶埃尔米特函数。首先,我将创建已知的函数值以及一个简单函数的一阶和二阶导数。

X = (0:.25:1)';
Y = sin(x);
Yp = cos(x);
Ypp = -sin(x);

接下来,我将使用slmengine以一种惰性方式创建一个SLM表单。这只是为了创建一个作为容器的SLM结构体。我之后会修改的。

SLM = slmengine(x,y,'knots',x);

现在,插入已知的导数信息。

Slm.degree = 5;
slm。Coef = [y,ypp,ypp];

并转换成pp形式。

Pp = slm2pp(slm);

这是函数sin(x)在这些结点上的五次埃尔米插值,以pp形式的样条表示。您现在可以使用MATLAB中的任何工具来处理结果,如fnval, fnplt, fender, ppval等。

Slm2pp能够将任何分段常数、线性、三次、五次或五次埃尔米特形式转换为相应的pp形式。

同样,这里没有真正的平滑处理。所以,如果你的信息是嘈杂的,不要指望你会非常高兴。结果将和你的信息一样嘈杂。

约翰D 'Errico

@Leandro -一个问题是,当你有多达二阶导数时,你问如何平滑噪声数据。在这种情况下,埃尔米特(五次)的结果并不能使数据平滑,它最多只能在这些点之间提供一个“平滑”的插值。如果你的函数值和二阶导数本身是有噪声的,那么得到的插值结果可能会很难看。

所以,也许你在问一个最小二乘样条,它可以在某种程度上平滑数据,使用关于一阶和二阶导数的信息来提供输入,但允许它们被平滑。这是可行的,尽管我从未见过有人问过这个问题。一个问题是如何解决函数值与导数中任何错误的惩罚。

不管怎样,你明确地表达了高阶插值的概念,但在同一句话中,你表达了对平滑的渴望。插值器从不做任何平滑。它所能做的就是在点之间提供平滑的插值。插值器总是在提供的点上恢复数据的精确值,所以平滑性只是点之间和结点之间的问题。

无论如何,如果你的目标和高阶埃尔米特插值一样简单,你可以通过将高阶埃尔米特插值的片段转换成pp形式来实现。然后ppval或fnval就足以处理由此产生的样条,用于插值。但是,如果提供的信息是有噪声的,那么结果就不会是非常平滑的。所以我不认为这能解决你的问题,尽管在这种情况下我能帮你。

莱安德罗Cryz

这是一个非常有用和强大的工具。我只是想知道我是否可以用5阶埃尔米特插值来平滑我知道一阶和二阶导数的噪声数据。matlab拟合工具的光滑样条不允许用户指定导数,尽管可以选择平滑程度,即曲线与三次插值样条或最小二乘直线的接近程度。如果这里有这个选项就好了。

莱安德罗Cryz

m F。

约翰D 'Errico

我不确定你所说的“任何这些限制”是什么意思。你可以做允许的事。我试着提供尽可能多的简单处方,但当然总会有我没有想到的东西。

如果导数总是递增,那么导数的导数总是正的。即二阶导数是正的。你可以通过设置'concaveup' 'on'来实现。

Gianna

很棒的工具——你能在绘制导数时应用这些约束条件吗?(也就是说,导数一定是递增的)

凯利卡尼

真正优秀的工具,非常有用。

一个小错误:如果您将带有nan的数据传递给slmeval,并且您的slm处方包括线性或立方外推,则会抛出错误(因为nan通过<,>检查,并且未在201-202行中分配给非零箱子)。小问题很容易通过预处理数据解决,但我花了几分钟才找到错误的原因。

马特·J

很好。不过,需要对.rtf文档进行一些编辑。缺少对一些参数的解释:xy,xyp,xypp等……

利奥

Jorge Yannie

谢谢这么好的工具!我真的很喜欢!

约翰D 'Errico

Jukka,

不,那不对。Mreg只是正则化部分。

这里需要用到几个不同的矩阵。

Mfit是设计矩阵。Mreg是正则化器。Meq包含等式约束,Mineq包含不等式约束。

一般来说,对于三次问题会有等式约束,可能会有不等式。如果你用的是单调性,那么问题中就会有不等式。

如果你有任何活动不等式,它们应该被认为是等式约束。

对于任何等式+活动不等式,它们需要在问题的设计和正则化部分之外进行处理。本质上,我们需要通过这些约束来减少问题。可以把它看作是在解决问题之前消除问题中的变量。

我可能需要考虑添加这个选项,因为它会变得有点混乱。

jukka

约翰,谢谢你的快速回复。我所说的有效自由度是指样条帽矩阵的轨迹。我需要找到帽矩阵来分析样条拟合的偏方差权衡。我试图找到帽矩阵的SLM等价,到目前为止,我最好的猜测是Mreg矩阵的左上角部分。这是对的吗?

约翰D 'Errico

@Jukka -有效自由度有点乱。

假设不存在不等式约束,则用待估计参数的个数减去不等式约束的个数。要估计的参数数目将取决于样条的阶数。对于有N个结点的三次样条,这是2*N个参数。假设是c2³,有默认的结束条件,有N-2个等式约束,加上你指定的任何其他约束。移位、缩放和归一化是不相关的——它们根本没有影响,除非它们可能对提高数值性能很重要。

困难的部分是是否存在ACTIVE不等式约束。不等式约束来自于单调性等。对于每一个这样的主动不等式约束,我们都应该减去一个有效自由度。

@Maria -你需要下载并安装这个工具箱才能使用它。这将要求您将工具箱目录添加到搜索路径中。

jukka

约翰,如何计算SLM样条拟合的有效自由度?我试过了,但是slmengine内部的样条设置。在所有斜率限制、缩放和规范化之后,M例程有点难以遵循。

玛丽亚Abizeid

亲爱的约翰,

我试图使用您的代码来确定ITC数据的拐点,但是它不适用于我的matlab R2015a。我已经安装了优化应用程序。错误信息如下:

Slm =slmengine(x,y,'degree', 1, 'plot', 'on')
未定义的函数或变量' slmengine'

如果我能做些什么来解决这个问题,请告诉我。

问候,

玛丽亚(女名)

ansi512

亲爱的约翰,
首先感谢你的贡献!做得好,绝对有帮助!

有没有一种方法可以包含二阶导数的最大值和最小值?

我试图处理重力流前端位置数据,并将最大加速度限制为g是我所拥有的确切约束之一……

先谢谢你,安瑟姆

Anael

出色的工作!它结合了你需要的一切,使样条成为一个强大的工具。忘掉Matlab的spaps、csapi、csape等吧。还有它们奇怪的参数约定。
一个缺点:坚固和自由的结选项不适合我。也许是我……如果有变化,我会更新的。

Anael

元君

嗨,约翰,

我还有一个问题。

我将每个数据点设为如下的结:

slmengine (x, y,“结”,“情节”,“对”,“冗长”,1);

看起来正则化不起作用。无论我如何调整正则化参数,都不会出现平滑效果。

但是,Matlab中的平滑样条函数也将每个数据点视为一个结,平滑效果明显。

所以,我想知道在Matlab中SLM和平滑样条之间的区别。

期待您的答复。

非常感谢!

最好的问候,

元君。

约翰D 'Errico

对不起。健壮的代码尚未实现。我已经开始写了,但只写了一半。我认为它被禁用作为一个选项,但我显然上传了另一个修复工具箱,而我在写作的过程中。

元君

亲爱的约翰,

感谢分享你的代码。

当我用你的代码进行拟合时,出现了一些错误。

这是我的代码:

slm = slmengine (x, y,“强劲”,“上”,“情节”,“对”,“冗长”,1);

错误信息:

slmengine>solve_slm_system错误(第2428行)
如果strcmpi (prescription.Robust,“上”)

调用期间未分配的输出参数"lambda"(可能还有其他参数)
“C: \用户桌面\ SLMtool \ \ YuanJun \ slmengine.m > solve_slm_system”。

slmengine>robustfit_slm_system错误(第2398行)
系数,λ=
solve_slm_system (RP, md, rhs、Mreg rhsreg,微地震,rhseq, Mineq, rhsineq,处方);

slmengine>solve_slm_system错误(第2429行)
系数,λ=
robustfit_slm_system (RP, md, rhs、Mreg rhsreg,微地震,rhseq, Mineq, rhsineq,处方);

slmengine>slmengine_cubic错误(第2332行)
coef = solve_slm_system(finalRP,Mdes,rhs,Mreg,rhsreg,…)

slmengine错误(第255行)
SLM = slmengine_cubic(x,yhat,prescriptionhat);

我不知道发生了什么。

有解决这个问题的办法吗?

再次感谢!

问候,

小君元

谢尔盖·P。

约翰D 'Errico

Xavier -我猜你要么没有优化工具箱,要么没有正确安装。SLM确实需要这个工具箱。

快速测试(运行2015a)显示您的测试在我的机器上运行良好。所以我看不出你为什么会失败。

泽维尔Sirault

亲爱的约翰,

我有兴趣使用SLM,但我遇到以下错误(使用Matlab 2014b和2015a):

>> x = - 5:0 .1:5;
Y = exp(-x ^2/2)/sqrt(2*pi) + randn(size(x))/100;
slm = slmengine (x, y,“阴谋”,“对”,“结”,15日‘积分’,1,“度”,3,' minval ', 0)

使用optimset出错(第148行)
函数'lsqlin'没有默认选项。

有解决这个问题的办法吗?

问候

泽维尔

迈克·

嗨,约翰,

关于robustfit_slm_system函数的问题:我不明白它是如何返回使用鲁棒拟合估计的系数的。从solve_slm_system函数(在处方之后调用)返回的数据似乎实际上是非鲁棒的。鲁棒设置为“关闭”)。很有可能我误解了代码,所以如果是这样的话,请提前道歉。

我的总体目标是看看是否可以将鲁棒拟合调整为分位数拟合,但我可能会使用权重设置。

谢谢你的想法。
迈克

约翰D 'Errico

哦,见鬼。看来我是时候重新考虑那些电话了。2015a现在也出来了,所以我会尽快修复。如果使用自由结,则使用fmincon来调整结,但使用lsqlin来估计样条系数。所以这两种工具实际上都在起作用。

迈克·

嗨,约翰,

伟大的工具。我用它来分类陆地卫星图像中30年来的土地覆盖变化。我在2013年大部分时间都在使用这个,然后在2014年使用了一点。

当我在2014b开始尝试时,我得到了与fmincon或lsqlin(不确定确切哪个)相关的警告,说“大规模”和“信任反射区域”选项存在冲突,而是使用“活动集”算法。此外,它还表示,在未来的版本中,这个警告将变成一个错误。

我不是一个优化专家,所以我想检查一下这是否会产生不同的结果或损害性能。我在数百万像素上使用自由的内部结,所以性能对我来说至关重要。

任何想法或建议都非常感谢。

谢谢,
迈克·
UCSB地理

迈克·

约翰D 'Errico

不。很抱歉,但是SLM可能永远不会在多个维度上工作,至少在我提供这个工具时是这样。

这并不是说某一天,有人不可能做到这一点。但是,我所允许的各种各样的约束条件在更高的维度上很难转化为有意义的概念。SLM背后的基本原理是,以一种允许用户简单地将他们关于系统的知识编码到曲线估计中的方式来估计曲线。

吴英

当我们有超过1个(比如3,4或更多)输入变量时,它是否有效?

约翰D 'Errico

Eshwar——我在编写代码时考虑过提供5阶或更高的匹配。然而,我没有这样做,因为正当的理由,至少我认为正当的理由。

-我很少需要三阶以上的订单。在这种情况下,我们通过复印机建模纸张路径,并且路径需要比三次样条所能提供的更平滑。

-对于许多最有用的约束条件来说,比三次的高阶是一个严重的问题。例如,单调性是使用基于Fritsch和Carlson论文中的不等式的一组必要约束来完成的。然而,比三次高的阶不允许这样好的解决方案,所以我们将有问题确保真正的单调性。曲率约束也将更加难以满足。

所以最后,我选择不实现高于三次的函数。对不起。

eshwar kannan

嗨,约翰,

如果我想让订单大于3,我该怎么做?直到3号我才从你的工具中找到订单。

问候,

拉贾

j .光伏

你好约翰,

感谢这个伟大的工具。

我确实有一个问题,我不确定是否已经得到了回答。我想把结点定义为曲线导数改变符号的点。有这样的选择吗?我使用的是分段线性SLM拟合,如果需要,我可以给你发一个我数据的例子。

谢谢,
朱迪思

约翰D 'Errico

穆斯塔法:我很高兴你喜欢它。

初始结的位置取决于您提供的位置,或者如果您没有提供任何位置,则使用默认位置。默认情况下,选择的结从最小(x)到最大(x)的间隔是相等的,总共有6个结,所以有4个内部结可以变化。然后优化器只改变那些内部结点。

在优化或初始值中没有明显的随机性。例如:

X = rand(100);
Y = exp(x);

明确的功能
Tic,slm = slmengine(x,y,'knots',6,' internorknots ','free')
运行时间为1.369497秒。

Tic,slm = slmengine(x,y,'knots',6,' internorknots ','free')
运行时间为0.176209秒。

Tic,slm = slmengine(x,y,'knots',6,' internorknots ','free')
运行时间为0.127645秒。

Tic,slm = slmengine(x,y,'knots',6,' internorknots ','free')
运行时间为0.123504秒。

Tic,slm = slmengine(x,y,'knots',6,' internorknots ','free')
运行时间为0.121428秒。

Tic,slm = slmengine(x,y,'knots',6,' internorknots ','free')
运行时间为0.123522秒。

Tic,slm = slmengine(x,y,'knots',6,' internorknots ','free')
运行时间为0.126947秒。

后续调用的时间差异很小,但不为零。这种可变性纯粹是由于你的CPU,因为它在后台不断运行各种其他事情。

总是多次进行这样的时间测试,并忽略示例中的前几次调用,因为第一次调用函数时,MATLAB需要额外的时间来缓存JIT解析的代码。上面,看到我做了一个清除函数首先清除函数缓存。第一个电话很慢,第二个电话之后,所需的时间要短得多,而且相当稳定。

约翰D 'Errico

我困惑。如果你找到这个页面,你应该可以点击“下载提交”按钮。完成后,解压缩文件,并使用addpath & savepath或pathtools将结果目录添加到搜索路径中。

yunt田

很好,但是我怎么下载呢?

穆斯塔法

亲爱的约翰
这是一个了不起的工具,非常感谢,肯定会在我的日记中提到。我有一个问题关于分段线性拟合使用免费,“interierknots”:我找不到如何启动第一节的优化值,我想弄出来为了实现单片机板,我会感谢如果你能告诉我,如何选择初始猜测基于fmincon函数所以我可以评估的复杂性和要花多少时间在印刷电路板上。另外,当拟合停止时,我注意到每次达到某些拟合所需的时间都不同(对于相同的选项),这意味着初始点不同,对吗?
问候,

约翰D 'Errico

对了,分段线性线段是存在的。将度“属性”设置为1或“线性”。

约翰D 'Errico

嗨西里尔,

如果您指的是SLM为分段线性情况选择结位置的能力,它在那里。你可以将' internorknots '属性设置为'free'。

如果你想要端点本身是自由的,我不认为有必要,只要这些结包含数据并放置在你需要的地方。

西里尔

嗨,约翰

应该是“xev =(0:.001:1)';”在教程的第二个单元格

是否有一种方法可以自动确定分段线性拟合中箱子的长度?它们可以有任何长度,但在数据发生重大变化时结束,任何想法,有趣的工作

约翰D 'Errico

约瑟,

关键是结点必须包含数据。如果这不是真的,它会抛出一个错误,告诉你一些类似的东西。事实上,我不知道你从哪里得到的想法,结应该完全位于数据的范围内,因为这不是我在教程中的任何例子中展示的东西。请注意,“结点”的默认值是一组完全跨越数据的6个等间隔点。

如果结点完全落在数据内部,而数据点则在数据外部,那么slmengine将被迫进行外推,这是我强烈反对使用样条曲线所做的事情,因为三次多项式段的外推实际上是随机的。

但是,如果我强迫您将数据包含在样条的结点中,那么您可以在整个结点范围内控制样条的形状。这就是这个工具的工作原理。它这样做有很好的理由。请注意,如果您确实希望进行外推,那么既然您可以控制样条的形状,那么就可以强制工具智能外推,至少在结的范围内。

约瑟夫

嗨,约翰,

非常感谢您的快速回复。

在特定的点关闭C2可能是我需要的,但我并不抱怨它不存在。此外,我没有意识到上下凹可以应用于多个区域,但我的模拟的其他方面并没有保持凹度不变。我非常感谢你的建议。

我知道我必须克服我的懒惰,开始为每个间隔使用定制的结来捕捉变化,避免过度拟合某些区域。

然而,我对slmengine.m的第176-178行有点困惑。

If (knots(1)>min(x)) || (knots(end)错误(…结不包含数据。数据范围:',num2str([min(x),max(x)])])

假设我的数据是x = 1:10,结点=[2,5,7](即包含在数据范围中的结点)。这将导致第176行求值为true,然后抛出一个错误。

(2 > 1) || (7 < 10) => true || true => true

(如果我没有弄错或混淆的话;但可能只是困惑)数据集的结位置不应该是可以接受的吗,因为所有结都在数据集的内部?

还是结点的值域必须包含数据值域作为子集?

抱歉,如果这是一个基本的问题,但我不明白把结点放在数据范围之外的意义是什么。

约翰D 'Errico

你好,约瑟夫,

我曾想过允许用户在特定节点关闭C2连续性,但就界面而言,这似乎有点笨拙。

如果你对这些断裂发生的地方有一个不错的想法,那么你可以在这些地方加一个或两个备用结。如果你想用半自动的方法来做,那么你可能需要分两次来做,使用第一次拟合来找到二阶导数断裂的大致位置。所以第一次打结时要打很多结。

您还可以指定一个区域或一组区域,其中曲线将向下或向上凹。确保这些区域不重叠,否则配合将被强烈约束而无用,并确保在每对连续区域之间有几个结。

最后,记住导数估计是一个不适定过程。所以这是一个噪声放大的过程。

约瑟夫

亲爱的约翰,

我非常感谢您的SLM工具(以及您所有其他提交和有用的提示)。

我有一个关于拟合单调增加数据(气体渗出数据)的问题,该数据将具有弯曲(由于在模拟期间随时间增加或保持温度,在渗出率上具有指数标度)。我能够很好地拟合原始数据,但我对样条的导数更感兴趣,因为它给了我关于渗出率的信息。

我期望导数总是正的(由于单调性),并且由于原始数据在温度变化时的弯曲,导数中存在尖锐的峰值。本质上,指数增长,然后指数下降,接着指数增长,指数下降,等等。

如果我将原始数据与在恒温行为区间上定义的单独样条拟合,那么在温度区间的边界处,一阶导数将出现跳变不连续,这是不可接受的。

举一个伪例子来说明我对一阶导数的期望

d = [exp (0:0.1:1) exp (0.9: -0.1:0.5) exp (0.4:0.1:1.5) exp (1.4: -.1:1)];

情节(d);

由于原始数据的样条拟合的平滑条件,我对峰被平滑一点很满意。我确实试过把C2改成" off "但是导数的每个区间都不够平滑。

当我知道我的一阶导数在一个区间内是平滑的但有一个尖峰时,有什么建议吗?

约翰D 'Errico

嗨,彼得,

是的,虽然我能理解你的困惑,但恐怕你误解了我的意图。

SLMEVAL不会查看您提供的处方来了解如何推断。实际上,它只看样条本身。(由于几个原因,处方字段作为模型的字段返回给您。例如,您可以使用该处方字段将类似的样条拟合到其他数据集,并将处方本身传递给slmengine。它还代表了您为构建样条本身所做的工作的一种文档形式。

在《帮助纪念》中,我引用:

“与我的推断相反,电影不会
推断。如果你想推断,那你
应该用不同的方式构造样条。”

关键是,如果您提供一个位于样条支持之外的点,它将使用样条在端点结处的值作为返回值。金宝app我想你可以把它看成常数外推。

关于需要“以不同的方式”构建样条,我的观点是,您需要提供扩展到您期望外推的区域的结。当你这样做的时候,现在你可以告诉slmengine如何在这些区域上构建样条,特别是在没有数据的情况下。在没有数据可以填补空白的情况下,作为用户的知识是至关重要的。

例如,因为你正在构建一个纯线性样条(与分段线性样条相反),甚至没有必要使用默认的6个等间隔的结。你可能会这样做:

X = linspace(5, 10, 100);
Y = 0.5 + 2* x + 0.001* x .^2;

slm = slmengine (X, Y,“阴谋”,“对”,“结”,(-50年,50),“度”,“线性”);
SLM (-10, SLM)
ans =
-19.704

看到了吗,现在slmeval可以在期望区域的任意点求函数值。

或者您可能已经为样条指定了结束条件。自然末端条件表示在样条的每一端都有零二阶导数的样条。由于这是一个两节三次样条,这迫使样条在整个范围内是线性的,尽管它仍然是显式的三次。同样,只要结一直延伸到你需要评估的地方,记忆就没有问题。

slm = slmengine (X, Y,“阴谋”,“对”,“结”,(-50年,50),“endc”,“自然”);
SLM (-10, SLM)
ans =
-19.704

即使在这里,SLMEVAL也不会外推到样条的结之外,除非作为一个常数。因此,如果我试图强迫它这样做,SLMEVAL将拒绝合作。

SLM (-100:20:100, SLM)
ans =
-100.3 -100.3 -80.154 -39.854 0.44588 40.746 81.046 101.2 101.2 101.2

不会生成这种行为的警告,尽管我想我也可以将其构建到SLM中。因此,下次更新SLM时,我可能会考虑添加一个“外推”选项。用户可用的选项可能是:

{“错误”,“警告”,“常数”,“线性”,“立方”}

因此,无论何时进行外推,“error”都会产生错误。'warning'会发出一个警告消息,但随后会推断为一个常量。“常量”是当前所做的。“线性”将从末端结线性地推断出来,等等。

我认为最符合逻辑的默认设置是“warning”,告诉用户正在发生一些奇怪的事情,尽管为了一致性,“constant”似乎是正确的。

最后要说明的是,在我过去的很长一段时间里,我曾经写过一个工具,它允许您根据与SLM工具中的想法推断现有的样条。也就是说,给定一条样条,它将为该样条附加新的结,并为该样条附加与用户提供的任何目标一致的形状。所以可以指定一个新的样条,保持旧曲线末端的形状,平滑地外推到一个特定的点,这样样条在那个区域是单调的,或者在那个区域是线性的,等等。我包含了一些方法来指定样条不能超过最大值,小于最小值,在末端有一个给定的斜率,等等。本质上,你想做的任何事情,都可以在外推的区域内进行。我想有一天我会编写一个类似的工具来使用SLM。

彼得棉花

教程给我的印象是,设置一个线性区域将允许在结点之外进行线性外推。我误解了你的意图吗?

X = linspace(5, 10, 100);
Y = 0.5 + 2* x + 0.001* x .^2;
slm = slmengine (X, Y,“阴谋”,“对”,“LinearRegion”,[-50,50]);
SLM (-10, SLM)

ans =

10.5209

> > slm.prescription.LinearRegion

ans =

-50年50

工厂

约翰D 'Errico

Leonid -是的,在过去我遇到过一些变量错误的问题,当问题是纯线性的时候,很容易解决。当你有样条曲线的时候,它就变得有点棘手了。抱歉,这不是SLM可以解决的问题。约翰

非常感谢您将形状语言建模放在一起并分享!

我希望你能回答我一个问题。当您使用MLS惩罚将样条曲线拟合到给定数据(或数据的一部分)时
数据除以X坐标,罚分在Y坐标计算。
但对于许多数据集,X和Y是对称的,在这些情况下,我认为这是一个自然的惩罚
从每个点到曲线/样条的距离的最小二乘,计算为一个点在曲线上的正交投影的长度。是否有一种方法可以使用slmengine以这种方式找到最优拟合?

约翰D 'Errico

Markus -你的问题是关于SLM中的自由结求解器。这里使用fmincon,因为在这种情况下问题是(部分)非线性的。尽管一些参数仍然使用直接线性求解器求解,但在这里,结放置参数进入非线性。

然而,您显示的链接是LP求解器的链接。我没有看到非线性代码,虽然有关于解决二次问题的能力的参考资料,因此最小二乘。(我承认我对CPLEX一无所知。)因此,据我所知,CPLEX不能用来代替对fmincon的调用。

当针对固定结问题调用SLM时,我认为CPLEX可能用于替换对LSQLIN或LSE的调用,但这似乎不是您的问题。

如果有人能提供更明智的回答,请随时提供帮助。

约翰

马库斯

哇,这真是一个很棒的工具。
是否有可能将使用的优化器从fmincom更改为CPLEX求解器?我希望用它能提高速度。不知何故,我不知道如何处理“intknots = fmincon(@free_knot_obj,intknots,A,b,…
[],[],[],[],[], [],[],fminconoptions,x,y,prescrip);”,特别是free_knot_obj函数,因为CPLEX期望有一个矩阵http://pic.dhe.ibm.com/infocenter/cosinfoc/v12r2/index.jsp?topic=%2Filog.odms.cplex.help%2FContent%2FOptimization%2FDocumentation%2FCPLEX%2F_pubskel%2FCPLEX1131.html在那一点上。有人能给我点提示吗?

约翰D 'Errico

只有当你告诉它结的数量时,这些结才会被等分。如果你给出一个结点的向量,那么它们就像你在向量中表示的那样。(阅读帮助!)

至于最佳位置,提供了优化内部结的选项。看看“internorknots”选项。如果您指定“free”,则它将在结位置上使用优化器。同样,您将通过阅读帮助来了解这一点。(注意,这只是一个优化。如果提供的初始值不理想,任何优化器都可能失败,因此,如果您对结可能属于哪里有一个很好的想法,它将有助于为结的初始选择提供一些方向。)

阅读帮助的建议非常重要,因为这个工具中有很多选项。你可能会对里面的发现感到惊讶。html值得一读。

Deepesh upadrashta

嗨,约翰,

非常好的工具。

我想知道如何用这个工具得到最优的分段线性函数。现在,我认为Xrange是等分的基于节数。对于给定数量的结点,如何得到X的最优位置,使数据最适合?

如果这个工具没有这个功能,你能建议其他的选择吗?

谢谢,
Deepesh。

约翰D 'Errico

玛丽亚——问得好。虽然埃尔米特形式最常见的是三次,但一般的想法也可以扩展到其他奇数阶,例如一阶,五阶,甚至七阶。

分段线性埃尔米特将是一个连续函数,由埃尔米特形式在结边界上共享一个函数值这一事实给出。它必须是连续的。

当我们提高两个阶到三次埃尔米特时,三次线段在结边界上共享函数值和一阶导数。同样,结果必然是连续的和可微的。所以我们可以建立一组处处可微的函数仅仅通过指定函数的值以及它在每个样条结点处的导数。(巧妙地选择这些数字是SLM在拟合过程中包含您的目标的同时实现的数据拟合。)

理论上,我也可以允许用户选择5度(或任何奇数度)。这里我们指定函数的值以及它在每个结点处的一阶和二阶导数。然后就会出现一些问题,因为单调性不再那么容易受到这样一个问题的约束。(对于那些想让我这么做的人,很抱歉,但比起我所提供的高阶样条曲线,当然与我所需要付出的努力相比,我所提供的样条曲线几乎没有什么好处。同样,像单调性这样的东西将变得更难约束。如果你需要额外的弹性,那么使用更多的结。)

关键是,一般的埃尔米特形式可以存在于任何奇数阶,尽管很少有作者选择这样做。在这段代码中,我还提供了一个分段常数形式,我个人认为它不是很有价值,但它很容易包含,即使它不是经典的赫米特形式。不管怎样,我相信我的一些用户已经用过它了。

我应该把这段代码写成使用b表吗?可以说,从那时起,我也可以不费多大力气地给出二次样条曲线。但我一直喜欢一般的埃尔米特形式,因为我可以直接从函数值和导数中看到系数和样条曲线的形状。同样,为各种约束编写代码也很容易。哦,好吧,我的代码,我微妙的偏见。

我希望这个漫无边际的回答能有所帮助。

很棒的工具箱,谢谢分享。

我有一个关于分段线性拟合的问题。在smlset中,它指定:
使用分段线性赫米特

分段线性拟合可以是赫米特吗?我搜索了赫米特拟合的定义,它总是以立方的形式出现。任何想法都会有帮助的!

斯文

当我长大后,我想像John D'Errico一样,做出直观的、非常有用的工具。

Zhexuan张

我还没想好该怎么做。有人能帮我吗?
我想要的是如何用自由结做一个3块线性曲线拟合,其中一块有固定的斜率。
例如,我想要一个线性的,常数的,线性曲线,其中两个交点是未知的。有我可以使用的内置选项吗?提前谢谢你。

Zhexuan张

SantiagoRojas

约翰D 'Errico

很久以前,我编写了一个工具,可以使用现有的样条,而不是简单地评估样条的第一个或最后一个段进行外推,我添加了一个具有所有所需属性的新段,如单调性,凹性,端点斜率或值约束等。当然,新的线段与样条的旧端点和该点的形状完全一致。如果需要满足指定的约束,我增加了几个片段。该代码的接口类似于SLM的接口,对于任何可能的形状都有许多可能的属性/值对。

我认为这个工具完全符合SLM理念,因为它鼓励用户明确地指定有关外推曲线形状的信息。虽然我想提供这样一个工具,但在我看来,更重要的是为SLM编写GUI包装器。

在很大程度上,当你第一次建立曲线时,你已经可以做那种形式的外推了。简单地指定出你需要曲线走多远的结。结不需要总是紧到数据的末端。(这是SLM的默认节点,但您可以选择自己的节点。)这允许您直接应用有关外推区域的任何相关形状信息。

neutrino4242

亲爱的约翰,

谢谢你的快速回答。你提到的马克·吐温让我对他的数学能力有了一个新的认识:-)。你是对的,这是一个哲学问题,当然,外推可能会导致意想不到的结果。但我的背景是数字/物理驱动的。我对给定时间序列的反卷积很感兴趣。频率响应=傅里叶空间中的磁化率是已知的。众所周知,扩展数据集=填充是必须的,以避免像振铃这样的边界效应。在图像反卷积的情况下,用作去模糊参见刘r .,“减少图像反卷积中的边界伪影”+谷歌。在《数值食谱》第13.1.1章中,建议使用零填充。如果数据集以0开始和结束,这是可以的,但在所有其他情况下都失败。 Zero padding leads to strong ringing at the beginning and end of the deconvoluted time series, independently of the padding length. The reason is the discontinuity in the data set before deconvolution. A better idea is the padding with constants to avoid the discontinuity. Next better idea is a extrapolation in the (unphysical) padded region where is no jump in first and second derivative. If i perform the deconvolution with such extrapolation, the ringing artifacts disappears. Of course, after deconvolution, only the time span without the padding regions in front and the end of the data set has a physical interpretation. I hope it explains my physical/numerical motivation of extrapolation with the first and last spline.

顺便说一句:我是德国人,我姓约翰。
ii)我使用slmengine主要是为了获得有噪声数据的数值导数。从我的角度来看,slmengine在控制噪声数据集的必要平滑方面有很多优点,例如凹化或积分。在更复杂的算法(如高阶方法或Savitzky-Golay-filters)中不可能实现这些(物理动机)特征。

约翰D 'Errico

嗨中微子,

你可以称之为不一致。我选择称之为强烈的意见分歧。实际上,这一切都归结于我的外推哲学,而不是PPVAL所体现的哲学。

我不允许您使用SLMEVAL来推断超出其支持的样条曲线。金宝app在你最不希望它发生的时候,外推会做傻事。也许我最喜欢的数学名言(几乎没有人知道)是马克·吐温的《密西西比河上的生活》。

“在一百七十六年间,密西西比河下游缩短了二百四十二英里。这是平均每年一英里三分之一多一点。因此,任何冷静的人,只要不是瞎子或白痴,都能看出,在古Oölitic志留纪时期,也就是一百万年前的下一个十一月,密西西比河下游有一百三十多万英里长,像一根鱼竿一样伸在墨西哥湾上空。出于同样的原因,任何人都可以看到,742年后,下密西西比河将只有一英里又四分之三长,开罗(伊利诺斯州)和新奥尔良将把它们的街道连在一起,在一个市长和一个共同的参事委员会的领导下,舒适地缓慢前行。科学有其迷人之处。对事实的小小投入,就能得到大量的猜想回报。”

关键是,外推做了一些讨厌的事情,所以SLMEVAL不允许你做任何事情,除了将外推作为一个常数函数超出样条的支持。金宝appPPVAL确实是这样。恕我直言,这是PPVAL的问题。

那么,如果你真的需要进行推断,你该怎么做呢?你应该在拟合样条方面做得更好!使用SLM工具的功能来拟合您想要的样条曲线。现在您可以完全控制形状,并且您应该监视结果,以确保您得到一些智能的东西,而不是像从PPVAL中得到的那样几乎是随机的东西。

换句话说,如果你不知道数据之外的曲线应该做什么,或者不愿意选择控制外推的形状,那么你就不应该将曲线外推到下面的区域。再说一遍,这是我的观点,但它似乎是一个非常合乎逻辑的观点,它与SLM的哲学完全一致。

neutrino4242

亲爱的约翰,非常好的工具,我在处理嘈杂数据的日常工作中广泛使用它。将在下一篇论文中给出参考文献。

可能是,我发现关于数据集外推的一个微小的不一致。看看这个示例代码:

目的:找到一个好的外推噪声数据,在最后的图中的绿线
清空所有,关闭所有;
x = 0:0.01:1.5 *π;
y = sin (x) +兰德(大小(x)) * 0.1;
xinterp = 2:0.01:3 *π;
matlab interp1不是为噪声数据设计的,失败了
yinterp = interp1 (x, y, xinterp ' pchip ', ' extrap ');
图(1);情节(xinterp yinterp);
%首先尝试使用slm,只有第一个和最后一个数据点在外推中填充
yslm = slmengine (x, y,“endconditions”、“估计”、“阴谋”,“上”);
yslmeval = slmeval (xinterp yslm);
图(1)、坚持、情节(xinterp yslmeval, - r); ylim (3 [3]);
%第二次尝试,这个工作,计算多项式在外推区域
ypp = slmengine (x, y,“endconditions”、“估计”、“阴谋”,“对”,“结果”、“页”);
yppeval = ppval (xinterp ypp);
图(1)、坚持、情节(xinterp、yppeval ' g '); ylim (3 [3]);

埃里克

谢谢你,约翰。根据你的建议,我重新拟合了我的数据,但不幸的是,结果比分别拟合曲线的两部分还要差。我做了一个简单的模拟,但我仍然得到了类似的结果。请您花几分钟时间看一下我的模拟数据,我将通过邮件发送给您。谢谢你!

我在这个网站上找到了Meyer写的代码。”http://www.stat.colostate.edu/~meyer/srrs.htm,但它是用R代码编写的,而不是matlab。我想这些天我应该学习R代码。Meyer也没有给出半凸半凹的数据如何拟合,我似乎还有很长的路要走。你能给我一些建议吗?谢谢你!

我期待你的新回复,再次感谢你。

约翰D 'Errico

不。SLM不使用截断的幂函数!这些通常是一种数值上较差的实现样条的方法,甚至只有三次样条。

SLM使用埃尔米特公式,我个人一直喜欢它,因为它们很容易观察和理解形状,只需要看参数,因为它们是由函数值和结点处的导数参数化的。这只是我个人的偏好,因为任何其他基础的样条仍然是样条。

至于单调性或凹性仅适用于有限范围,您可以直接使用SLM来实现。阅读slmset的帮助。它(部分地)说:

“递增”-控制函数的单调性
= 'off'——>样条的任何部分都不被约束为an
增加的功能。
= 'on'——>函数将在其整个域内增加。
=长度为2的向量——>表示a的起始点和结束点
曲线单调递增的区域。
=大小为nx2—>的数组,每一行表示开始
以及曲线所在区域的端点
单调递增。

因此,如果您希望约束仅适用于曲线的一部分,则可以指定区间。同样的方法也适用于凹性约束。如果该约束将表明曲线仅在部分结区间上单调,我将拉伸它以要求在整个结区间上单调。所以你不能在一对结中间停下来。在这种情况下,只要打个结就可以了。

埃里克

约翰,你能告诉我是否有可能拟合这样的曲线:单调的“增加”,“凹”在前半部分,“凹”在后半部分。

为了适合上面的曲线使用slm工具,我把曲线分成两半。然后我使用slm工具两次分别拟合曲线的两个部分。结果不太好。

slm工具能解决这个问题吗?期待您的早日回复。

埃里克

约翰,我想我已经找到问题的答案了。

首先,我认为你在SLM工具中使用的基样条是截断幂函数,这种函数对低程度的样条是有效的(例如。在Ramsay的论文中,他提出i样条将是一组更合适的基样条,可以线性组合以产生与结序列相关的任何其他样条。我想知道是否可以在slm工具的后期版本中添加I样条的应用程序。

第二,他的“slm.stats”。回归样条曲线的平滑参数?根据“slm_tutorial. net”中的示例。m”,我可以得到很多“RP”,最后一个是8.9左右。

我想你这些天一定很忙。祝你永远好运。谢谢你!

埃里克

约翰,我想我误解了"三次样条"。“三次样条”仅表示样条的次数为3。我可以选择不同的样条基函数组成三次样条,如m样条、b样条或I样条。Ramsay给出了3次i样条线性组合的单调三次样条拟合的几个例子。

John,如果我用3次三次样条进行曲线拟合,你能告诉我SLM工具中你选择的样条基函数是什么吗?

期待您的回复,再次感谢。

埃里克

谢谢你,约翰。我从你的评论中得到了很多答案。

我对“三次样条意味着你有一条由分段组成的曲线”有点困惑。在Ramsay的论文中,他给出了一个将6个i样条组合成最后样条的例子(见Ramsay论文图1)。在SLM工具中,我是否可以将“分段分段”视为“I样条”或“其他样条”基函数?

谢谢你的更新,你能解释一下“slm.stats”吗?finalRP”?如果你能给出一个关于“slm.stats”的例子就更好了。“slm_tutorial.m”中的“finalRP”。

再次感谢你。

约翰D 'Errico

不好意思,我没有迈耶的论文不知道他们的术语是什么。次3是SLM中的三次样条。

我现在记得拉姆齐的论文很有用,但我从柯达退休后,我的大部分旧论文都被留下了。

如果你设置30节,那么结果是一个三次样条。三次样条意味着你有一条由分段组成的曲线,因此有30条,每条曲线在结处相连,因此它们在这些结点上足够光滑。

当前版本的SLM没有返回由交叉验证生成的最终参数,但是我已经对它进行了修改,使其能够返回。现在,finalrp将包含该值。我明天早上上传新版本。反正也该更新了。

埃里克

谢谢你,约翰。谢谢你,彼得。
我读了J.O. Ramsay写的论文,经过比较,我更加感受到Slm工具的优秀。

约翰,我对slm工具还有一些问题,你能给我一些建议吗?
首先,如果我在“slmengine”中选择3次,是否意味着我选择三次样条进行曲线拟合?我看过Meyer的论文,他说I样条是m样条的积分,c样条是I样条的积分。c样条是三次样条的另一个名字吗?

其次,如果我为我的数据设置30节和3度,那么Slm工具的输出曲线是由30个三次样条的组合组成的吗?这些三次样条的位置是由结点的位置决定的吗?

最后一个问题,我发现您的Slm工具提供了“交叉验证”来帮助平滑曲线。我可以通过在“slmengine”中设置“交叉验证”来获得最佳平滑参数吗?

期待您的回复,再次感谢。

彼得•西蒙

@erick:关于回归样条的一个很好的文献可能是J.O. Ramsay,“单调回归样条的作用”,这被后来的作品大量引用。一份副本可以免费从http://tinyurl.com/cqekokb

约翰D 'Errico

埃里克,对不起,我在这方面没有积极的研究,我也没有任何新的论文。我记得Wright和Wegman关于约束回归样条的一篇论文,但那是30多年前的事了。我在开发SLM方面所做的工作主要是我自己的,基于我的咨询活动,尽管我从未发表过任何关于该主题的论文。

埃里克

谢谢你,约翰。我想我从你的评论中得到了一些答案。Fritsch和Carlson给出了插值的理论,而SLM是回归的工具。我的数据是有噪声的,所以我需要一个回归工具,而不是插值工具。再次感谢你。

另一个问题,你能给我一些关于SLM工具关于“单调分段三次回归”理论的参考吗,我找到了meyer写的一篇论文,那就是“Inference using shape-restricted regression splines”。但是Meyer很少提到“单调分段三次回归”,请给我推荐一些参考文献,谢谢。

约翰D 'Errico

Erick -是的,那篇论文就是我(很久以前)读到的关于三次函数单调区域的文章。对于包含所有单调立方段的区域,我使用了一个多面体近似(6或7个边,我现在想不起来确切的数字了)。

那么,SLM中使用的理论与Fritsch和Carlson提出的理论完全相同吗?不完全是,因为它们描述的是插值样条,而且我使用了一个不同的,比它们实现的更具包容性的区域。

至于结的位置,这是传统上这类样条最大的问题。一个结属于三阶导数变化的地方,但这很难识别。SLM背后的思想通常是使用比实际需要更多的结,然后根据您对工艺的了解,对曲线形状应用巧妙的约束。这就是SLM的优势所在,它允许您将您可能拥有的关于关系的任何信息带入建模过程。

埃里克

非常出色的工作。谢谢你!
我有两个关于单调数据拟合的问题。第一个:我找到了一篇论文“单调分段三次插值(SIAM J. number)”。分析的,17(2), 238–246
)”。如果我使用您的SLM工具进行单调数据拟合,您的SLM工具下的理论是否与本文相似?
第二个问题:我不知道我应该选择多少个结点来进行数据拟合,我的曲线是一个平滑的阶梯曲线,如果我选择太多的结点,结果是错误的。但如果我选择的结不够多,结果就不好。我只是选择相等的间隔来设置结的位置。
期待您的回复,再次感谢。

埃里克

非常出色的工作。谢谢你!
我有两个关于单调数据拟合的问题。第一个:我找到了一篇论文“单调分段三次插值(SIAM J. number)”。分析的,17(2), 238–246
)”。如果我使用您的SLM工具进行单调数据拟合,您的SLM工具下的理论是否与本文相似?
第二个问题:我不知道我应该选择多少个结点来进行数据拟合,我的曲线是一个平滑的阶梯曲线,如果我选择太多的结点,结果是错误的。但如果我选择的结不够多,结果就不好。我只是选择相等的间隔来设置结的位置。
期待您的回复,再次感谢。

C J

桑托什

假设导数奇异意味着导数函数的不连续,我想知道是否有一种方法可以使样条曲线合理地拟合阶跃函数。

桑托什

我对你的教程中的一个例子有一个问题。
导数奇点是什么意思?这可能是一个幼稚的问题,但我没有在任何地方看到这个的定义。

桑托什

Matlab2010

杰夫生气

这个包可能是我从Mathworks下载的最有用的包。在发现它之前,我自己研究过一些特定情况下的问题(拟合单调函数,拟合具有简单峰值的函数),只是取得了有限的成功。谢谢你,约翰。

约翰D 'Errico

Tim -是的,默认情况下,SLM确实产生C2(两次连续可微)近似。当然,你可以随心所欲地改变它。

而且,是的,SLM背后的整个思想是,它为您提供了一个很好的匹配,允许您将自己的信息构建到问题中,同时不要求用户提供显式模型。

蒂姆

我发现非参数“拟合”的整个想法非常有趣,因为我有一些数据,我没有一个函数来拟合数据。我有位置和时间的数据点,我需要得到加速度和时间的关系。我发现不同的拟合函数肯定有不同的导数行为,那么SLM会给出一个可靠的二次可微的拟合吗?你指出它给出了拟合加上导数。

如果这能以一种我有信心的方式工作,那将是天赐之物!

约翰D 'Errico

这个问题很有趣,但是很难解决,因为使用的优化器类涉及到三次多项式。我将首先讨论如何实现一个更简单的约束。例如,假设您对曲线左端函数的值定义了一个绑定约束,那么您可能会为LeftMinValue提供一个处方。

这相当于在样条参数上设置一个不等式约束。更重要的是,我可以把不等式约束写成线性形式,这样这些参数就可以线性地进入方程。由于SLM工具将使用线性求解器(在本例中为LSQLIN)来解决问题,因此这是必要的。LSQLIN是一个快速、高效的优化器,它可以快速、一致地返回您的答案。同样重要的是,您应该意识到LSQLIN不像许多其他优化器那样需要初始值。

单调性是一类较难定义的约束。诀窍在于回到PCHIP的工作原理上来。PCHIP是基于Fritsch和Carlson的工作,他们展示了如何在三次多项式的参数集上设置边界,使其在固定区间内是单调的。结果表明,参数集在相关参数空间中简化为一个具有凸但弯曲边界的区域。我用一个稍微小一点的多边形边界来近似这个弯曲边界。好的是多边形域可以使用LSQLIN允许的线性不等式约束来定义。有效地,SLM搜索的可能样条曲线的集合略小,总是满足所需的单调性约束。这就是我所说的SLM在这种情况下使用一组足够的约束的意思。可能还有其他的样条曲线能更好地拟合数据,但我找不到。这里的区别很细微,但通常不那么重要。 Effectively, the sufficient constraint makes the spline slightly less flexible. So if you really desperately need a more flexible spline, you just use an extra knot or two. No problem.

对MinSlope或MaxSlope的全局约束通过转化为单调性问题而简化,因此也很简单。

那么,当你想要强制执行一个通用的MaxValue或MinValue规定时,会发生什么呢?这是我必须使用这些必要但并不充分的约束的唯一情况。对于一个区间内的三次多项式的最小值,没有解(据我所知,而且我已经找过了)允许我使用线性代数和线性不等式约束来强制执行该约束。因此,尽管我能够使用对LSQLIN的调用来解决单调性问题,但我必须为全局最大值或最小值使用最好的必要约束。从本质上讲,我在每个结区间的一组固定点对函数进行采样,限制函数不超过期望的值。由于这些点相当接近,那么函数将不会超出您的全局边界太多,但这是我实际可以做到的。

另一种选择是强迫SLM使用不同的求解器,也许是FMINCON。FMINCON将这个问题放到了一个完全不同的类中,一个通常您不希望去的地方。FMINCON在收敛特性上会慢得多。它将需要参数的起始值。有时FMINCON不会收敛到你喜欢的解。除非绝对必要,否则不要使用FMINCON。对于这些问题,LSQLIN是一个更好的解决方案,但是使用LSQLIN迫使我使用纯粹必要的约束。它们可以允许有少量超出界限。这就是生活。

在解释了为什么我不能在SLM中完全解决您的问题之后(我挥了很多手,但我希望我明白了这一点),您并没有完全迷失方向。通常,这种全局约束是更深层次的反映。例如,如果你绝对知道你的函数永远不会是负的,那可能是因为你真的在错误的领域工作。也就是说,如果Y可能永远不会是负的(或零),那么为什么不在域log(Y)中工作呢?

实际上,我建议可以构建log(Y) = f(X),或者Y = exp(f(X))模型。这很容易做到。您只需在将Y变量传递给slmengine之前记录它。可能需要调整一些约束以保持在上下文中。因为这是一个很好的问题变换,单调性甚至不受影响。如果曲线以前是单调的,现在仍然是。甚至不需要提供零处的MinValue约束。这个全局最小值内置于您的转换中。当然,如果你有一个Y值为0的点,这将失败,但除此之外,它应该工作得很好。

问题的关键是,这种对值的全局约束通常是一个具有域的问题的反映。这是一个信号,表明你确实在错误的领域工作。这种转变只会把你带到正确的工作地点。

这样的转换总是最好的解决方案吗?并不是所有的问题。记住,当你变换Y的时候,你也改变了错误结构。有效地记录Y意味着你现在假设了一个对数正态误差结构,所以你的误差现在是成比例的。现在,接近零的数据点将对解决方案产生更大的影响。在一个非常接近于0的点上,一个微小的误差,一旦你记录下来,将会是巨大的。这可能合适,也可能不合适。

现在,你提到了一个同时拥有全局MinValue和全局MaxValue的情况。这里的逻辑变换是基于某种类似的s型函数。例如,假设您的问题已知在-1和1的范围内。简单地将问题转化为

Y = erf(f(X))

然后将变量X和erfinv(Y)传递给slmengine。类似的变换也适用于真sigmoid,一般形式为1 /(1+exp(u)),或关系atan(u)。任何有解析逆的单调有界变换在理论上都是可行的。

同样,这些转换可能会彻底破坏错误结构。一个解决方案是使用基于您所使用的变换的局部导数的权重。这很容易通过传入适当的权重向量来实现。

唯一可能的替代方案是提供保守一点的MinValue或MaxValue。这在函数超出实际边界之前给了必要的约束一些空间。问题是给它多少空间,这是一个无法回答的问题。(对不起)。

所以,如果你在没有睡着的情况下读完了这篇文章,我很抱歉我不能提供一个完美的解决方案,但有一些想法可能对你有用。- - - - - -约翰

马克

非常好的代码,谢谢John。
只有一个问题,我想在最大值和最小值之间有一个约束样条,但是有了“maxvalue”和“minvalue”,你说(我尝试了一下,它发生了):“这个约束只是一个必要的约束。这是不够的。在某些情况下,样条曲线可能略高于这个最大值”。有办法避免这种情况吗?
为什么不是呢?这是一个公式问题还是一个数值问题?因为它是数值的,我想我可以处理它。

谢谢

安德鲁的邮票

约翰,
感谢这个优秀的工具。我要是早点发现就好了。多年来,我一直在编写自定义的二次程序来拟合具有各种约束条件(单调性、凹性、端点斜率等)的多项式,但似乎每次都需要在我之前所做的基础上进行轻微的变化。这个工具捕获了我正在做的所有事情(以及更多)。

约翰D 'Errico

马特,这不是预测的不确定性,而是参数本身的不确定性,在这种情况下,是结点位置的不确定性。为了做到这一点,你可能想尝试一个自举估计器。

http://en.wikipedia.org/wiki/Bootstrapping_(统计)

马特

嗨,约翰。这是一个很好的工具!我有一个问题。文件附带的.rtf文件列出了处方。“预测不确定性”作为一个选项。然而,文件本身却没有。是否有任何方法可以梳理出为自由结选择的“x”值的不确定性/置信区间?详细输出列出了'预测误差范围',但这似乎在'y'中。我用的是线性的3结配合。

约翰D 'Errico

实际上,'rmse'不是一个属性,尽管你可以做你想做的。我在编写代码之前编写了该文档,然后错过了修改文档以反映设计中的微小变化。我只是将这种能力融入到“正则化”属性中。如果为该属性提供了负值(-r),则使用r作为RMSE的目标来拟合样条。帮助信息正确地告诉了你这一点,但是帮助信息很长,很容易被忽略。

菲利普·劳赫

约翰,
感谢您提供这个伟大的工具。我用它来适应变形的聚合物细丝,它做得很好。我试图使用您的文档中描述的“rmse”参数。然而,代码中似乎没有这样的属性。它是否已被删除(由于频繁的天空坠落事件),或者我是否必须以与其他属性不同的方式设置rmse属性?例如,设置'endconditions'属性就可以了。
非常感谢,
菲利普

约翰D 'Errico

Per - SPLINEFIT和SLM是完全不同的工具,有一些不同的设计目标。

SLM的基本原理是,作为用户,您拥有关于要建模的系统的知识,并且通过包含这些知识,您将获得更好的模型。SLM提供了一种工具,可以高效、智能地将这些知识引入建模过程。作为样条,SLM是正则化的样条,因此SLM中的结点位置不像SPLINEFIT那样重要。即使你有比数据点更多的结点,如果可能的话,SLM仍然会产生一个好看的结果。例如,用这两个工具试试:

X = rand(5,1);
Y = sin(x);
Pp = splinefit(x,y,10);
Fnplt (pp) %在曲线拟合工具箱中
SLM = slmengine(x,y,'plot','on','knots',10);

同样,SPLINEFIT可能应用的约束数量是相当有限的,而正则化的使用允许这不是一个问题。同样,这有效地阻止了你试图构建一个真正单调的三次样条曲线。

SPLINEFIT只对函数值和指定位置的导数提供非常有限的约束。这使得无法保证三次(或高阶)样条的真正单调性。SLM中各种各样的约束以及与这些约束的自然接口使它(恕我直言)更加有用。

另一方面,splineft为那些真正需要高阶可微性的人提供了高阶样条。当然,从有噪声的数据中估计高阶导数几乎是不可能的,这也是事实,所以如果你试图这样做,你可能是在开玩笑。SPLINEFIT还允许一个强大的拟合选项,一个有用的想法,我已经被鼓励提供在我的下一个版本。

SPLINEFIT提供的另一个功能是在一次调用中解决多个问题,而我认为外部循环是一个足够的解决方案。无论如何,由于每个问题都是不同的,我建议您建立一个模型,并在继续之前确定您是否满意。

最后,这两个工具都很有用,并且提供了将样条拟合到数据中的能力。就我个人而言,我认为SLM是迄今为止我最喜欢的,但你不能因为我在这个方向上有偏见而责怪我。

每Nordlow

SLM与FEX splinefit包相比如何?

约翰D 'Errico

嗨,马修,

SLM有一些简洁的功能。我试着把每个人都需要的东西都放进去,尽管我永远无法完全实现这个目标。您基本上可以在这里实现您的愿望,但您需要探索SLM的选项。试试这个例子:

X = rand(50,1)*6 - 3;
Y = erf(x);
slm = slmengine (x, y,“阴谋”,“对”,“结”,[3 -1.5 - 1.5],“增加”,“上”);

对于3段,一个纯三次样条做得不是很好。假设我们提供了一些信息,函数在第一部分和最后一部分上应该是线性的?线性区域属性就是这样做的。在结处要小心,这样它就不会混淆,并试图强迫中心区域也是线性的。

slm = slmengine (x, y,“阴谋”,“对”,“结”,[3 -1.5 - 1.5],“增加”,“对”,“linearregion”,[3 -1.6;1.6 3]);

为什么失败了?因为默认情况下,SLM是一个C2(两次连续可微)函数。二阶导数是连续的。这对只有3节的内部结点来说是个很大的约束。通过放松C2连续性,我们可以做得更好。

slm = slmengine (x, y,“阴谋”,“对”,“结”,[3 -1.5 - 1.5],“增加”,“对”,“linearregion”,[3 -1.6;1.6 3],c2,“关闭”);

如果您研究结果段的系数,您会发现第一个和最后一个段确实是线性的,尽管它们被表示为立方体。前两个系数为零(在浮点垃圾内)。事实上,这里的第一部分简化成了常数。

Pp = slm2pp(slm);
pp.coefs
ans =
-5.8398e-16 -0.99183
-0.14716 0.6624 -4.2825e-16 -0.99183
2.7139e-16 -6.6613e-16 0.0011762 0.99655

在零处加上一个备用结,曲线就开始看起来更像erf了。

slm = slmengine (x, y,“阴谋”,“对”,“结”,[3 -1.5 0 1.5],“增加”,“对”,“linearregion”,[3 -1.6;1.6 3],c2,“关闭”);

不可否认,只是给它打一些结也很有效。

SLM = slmengine(x,y,'plot','on','knots',[-3];25:3),“增加”,“上”);

马修·福尔曼

约翰,

这个工具很棒。我一直在用它对运动捕捉相机的运动数据进行分段回归。

我有一个问题。我已经搜索了论坛的高低(我确信它存在的地方,我只是错过了它),并一直无法找到一个简单的方法来改变一个单一的拟合样条的程度。

例如,我想用4个结来产生三个不同的线段,并且能够改变线段的程度,这样开始是线性的,中间是三次的,结束是线性的。

提前感谢您的帮助!再说一遍,这个工具很棒!

马特

谢赫。

一部精彩的作品!
感谢John转发SLM。

约翰D 'Errico

克里斯-对不起。这是代码中的一个错字,经过修复并重新提交,将于今天早上出现。它只有在使用某些约束组合时才会表现出来,所以我在测试中错过了它。

克里斯·范德·托特

嗨,约翰,
我得到一个错误时使用
以以下方式运行引擎;

Slmengine (x,y,'degree',1,' internorknots ',' free','knots', 3, 'left - slope', 0, 'rightminslope', 0);

???在202处使用==> lsqlin出错
A中的行数必须等于b的长度。

==> slmengine>solve_slm_system在2333时出错
[coef,junk,junk,exitflag,junk,lambda] =…

当我查看对lsqlin的调用时,Mineq有三个值,而rhsineq只有两个值。
Mineq = [0 0.5 -0.5];
Rhsineq = [0 0];

这是一个错误,还是我错误地调用了slmengine。

问候,

约翰D 'Errico

DF:对不起,现在不行。对于高阶样条,一些约束(如单调性)变得更加难以编码。虽然它们可以以必要的形式表示,但它并不能真正约束曲线具有所需的性质。

DF

SLM可以使用任意阶的样条吗?我想把它用在4阶和5阶样条上。
谢谢你!

约翰,

我刚刚给你发了一封邮件,关于一个关于将分段常数曲线拟合到近似正态分布的问题。但是,我想我也会把这个问题贴在这里。我需要pw常数曲线有13块,但我希望结自由间隔,但我注意到在你的评论中,pw常数曲线有麻烦。还有别的办法吗?

如果没有,是否有一种方法可以使最后一个内部结位于分布的平坦部分(右尾)的开始,然后其他部分适合曲线的中心部分,其中曲线变化迅速。

再次感谢您的巨大贡献!我在论文的几个部分都使用了您的工具。

谢谢你!
Britnee

约翰D 'Errico

罗恩-谢谢你找到了重量bug。我会发布一个带有修复的新版本。至于推荐信,我真的不知道。其基本原理有点像贝叶斯理论,即利用物理系统的知识进行建模,从而产生与先前信息一致的可行模型。在实践中,我发现它非常有效,并且已经使用了20多年的类似方案。我做过很多关于建模哲学的演讲,但没有发表过论文。我认为,使SLM工作得如此出色的是使用了一种简单的方案,将您对系统的知识编码为描述曲线形状的一组定义良好的参数。

罗恩电子乐

这些例程非常有用。希望阅读更多关于这些例程的数学基础。你能推荐一些除了基本的最小二乘样条参考之外的阅读吗?

此外,我做了以下关于处理重量的更正…

数据中是否有NaN或inf元素?
K = isnan(x) | isnan(y) | isinf(x) | isinf(y);
如果任何(k)
%将它们从分析中删除
X (k) = [];
Y (k) = [];
prescription.Weights(k) = [];%也降低相应的权重,2011年5月
N = length(x);
结束

%如果设置了权重或错误条,请验证它们的大小
%参数,与数据点的数量相比。

皮特

除了所有这些非常聪明(高级)的东西,还有一个在分段线性回归中找到拐点的非常方便的方法。整洁的=)

看到的://www.tatmou.com/matlabcentral/newsreader/view_thread/298989

约翰D 'Errico

听起来你想让结变化,但只在设定的范围内?如果是这样,我建议将对slmengine的调用放在包装器(fmincon的目标函数)中。使用它来改变结的位置,与slmengine现在看到一个固定的结列表。

事实上,当你指定自由的内部结时,这就是slmengine所做的改变结,所以有人可能会说我可以把它作为slm的另一种选择。问题是,界面会有点混乱,想出一种允许用户指定部分或所有结的边界的方法。

如果您通读代码,您将看到在这种情况下我是如何调用fmincon的。注意,我约束结点是不同的。

再问一遍我是否误解了你的目标。

凯文·斯蒂芬斯

出色的软件包,它几乎满足了我的所有需求,但我只是想知道如何在一个自由的分段线性hermite中插入一个半径?显然,我可以在优化后再做,但对于更大的半径会有明显的错误。

Royi Avital

约翰,谢谢你的回复。
我会按照你的建议引用。

我会试着看一看德布尔的书。
我只是想知道这个工具背后扎实的数学原理。
希望我能从那里开始。

有一天,如果你写了一篇关于它的文章或笔记,我很乐意阅读和学习。

谢谢你!

约翰D 'Errico

我希望我在几年前编写这个工具的第一个版本时就写了一篇关于这个主题的论文。当时我并没有这样做,尽管我已经就这些工具的底层建模哲学做了一些演讲。

其基本思想是简单的最小二乘样条,加上平滑样条这样的平滑惩罚。平滑度惩罚解决了许多情况下任意(差)选择结的问题。

一般的最小二乘样条在文献中有深入的介绍,平滑样条也是如此。对于这些基本思想,德布尔当然是经典的参考,一本值得任何样条曲线使用者阅读的书。

SLM工具添加的东西是我从未在文献中看到过的。这是一种对曲线形状进行智能选择的约束可以作为结果的强大、有用的正则化器的思想。它们允许您将自己关于系统的知识构建到模型中,使用简单的词汇来描述该曲线的所需形状。

几年来,我看到人们使用奇怪的非线性回归模型来拟合曲线,只是因为他们需要一个给定形状的曲线,所以我编写了这些工具。所以用户选择一些非线性的s型,高斯型,等等,没有更好的理由,只是因为它符合一些基本的期望形状。当然,非线性回归也有自己的问题,比如初始值不好,缺乏收敛性等。更糟糕的是,用户发现他们选择的曲线形状并不是真正正确的形状,所以他们最终明显缺乏契合度。一旦有了一个可行的工具来拟合这些曲线,我发现很少有人会因为错误的原因而使用非线性回归模型。

zip文件中有两个文件讨论了这些想法“slm_tutorial.html”和“shape prescriptive modeling.rtf”,但我只能提供这些了。如果您确实需要明确的参考,我们还建议了文件交换工具的引用格式。你可以在这里找到我们的建议:

http://matlabwiki.mathworks.com/Citing_Files_from_the_File_Exchange

Royi Avital

有什么文章可以作为这种配件的参考吗?
我想在我的项目中使用这个工具,并想用一些背景信息来备份它。

感谢这个神奇的工具。

维塔利Koissin

亲爱的约翰,事先非常感谢你!

-如果碰巧你在下周之前有时间应用这个二阶导数约束,那就太好了:-)然后我将在即将发表的会议论文中包含更好的近似。

-你说得对;我只是对一阶导数中出现的几个平台点感到困惑。但是正如在帮助文件中已经强调的那样,这意味着“=>0”(或“<=0”)意义上的单调性,而不仅仅是“>”或“<”。

-好吧,当我有很多点需要插值时,总弧长约束并不是至关重要的(对我来说,从测试数据中取很多点不是问题)。

约翰D 'Errico

-我应该能够在曲率的趋势上添加一个约束。实际上,我要做的是允许用户限制三阶导数的符号。结合对二阶导数符号的约束,这将允许你根据需要创建一个曲率增加或减少的函数。

-一阶导数单调性的约束(增加或减少)已经存在,其形式是凹凸性。我将在帮助中添加注释来强调这一事实。

-对曲线的总弧长进行约束是困难的,因为这是一个非线性约束。当应用该约束时,这将迫使使用非线性优化器,如fmincon。

维塔利Koissin

非常感谢这个工具!我用它来拟合由其自身重量负载的纺织品条纹弯曲形状的测试数据,而SLM是我用于此的最佳拟合!

但是:-)我会很高兴,但更多,如果你扩展文件,包括以下属性:

1)单调的曲率增加/减少(在我的情况下,曲率减少的条件非常重要,因为我取二阶导数来计算条纹的弯曲刚度)。现在我需要进行双重拟合:首先是弯曲的形状,然后是斜率;否则曲率有太大的跳跃。但即使在此之后,结果仍然不完美:-(

2)控制曲线的长度(类似于积分选项)。这在我的情况下不是很重要,但可以改善拟合,因为这种情况在我的问题中具有良好的物理意义)。

一阶导数单调增减的性质也很有用。

最好的问候,
维塔利

mathworks2011

非常强大。

约翰D 'Errico

不,附件中的电子邮件地址是正确的。我不记得看到过你的电子邮件,但我确实收到了大量的电子邮件,所以你的邮件可能丢失了。

如果根据基本原理,你想强迫曲线通过一组给定的点,这已经在那里了。你可以通过设置“xy”属性来强制曲线。所提供数组的每一行定义一个点,作为(x,y)对。注意,如果您在单个结间隔中指定几个点,则可能无法解决问题。

由于slmengine总是返回样条模型,因此任何简单的操作模式都可以通过为slmengine创建一个包装器来实现,然后调用slmeval。

Royi Avital

这是一个很棒的工具。
然而,我错过了两个选择:
1.“简易操作模式”-插入3个向量- x, f(x), x'。结果是外推的f(x')。
2.在一些数据点上设置“基本事实”。

我试过给你发邮件询问相关事宜。
可能是你个人资料里的电子邮件地址错了。

感谢分享这个伟大的工具。

Royi Avital

皮特·谢尔

您是否计划将这个优秀的工具扩展到多个输入参数?类似于MARS或更简单的东西将为用户提供出色的数据表面拟合工具。

约翰D 'Errico

我感谢Mark Shore抓住了曲率约束的一个问题,这个问题只在某些情况下出现。修复已经提交。

约翰D 'Errico

Kay -虽然我很想帮助你(以及许多其他要求置信区间的人)并为这个工具提供置信区间,但它们在大多数情况下都是无效的。当涉及到不等式约束时,线性回归置信区间的标准方法就变得不合适了。这个工具的许多最有用的方面都涉及到不等式约束。更糟糕的是,如果算上自由结,情况会变得更糟。

虽然理论上我可以使用更复杂的技术来提供置信区间,但这些技术将非常耗时。

约翰

程序能否确定估计参数的95%置信区间?

马克海岸

谢谢,约翰,这正是我想要的。没有想到查看faq。

为了补充我前面的评论,SLM函数的命令行参数简洁但合乎逻辑且直观。我需要非常精确地插值到具有多个拐点的密集测量噪声数据,并且能够在我使用这些工具的第一天获得非常满意的结果。

约翰D 'Errico

引用FEX的文件似乎已经够频繁了。我们想出了一些想法,并把它们放在这个链接上:

http://matlabwiki.mathworks.com/Citing_Files_from_the_File_Exchange

马克海岸

确实令人印象深刻。快速,非常灵活,易于使用。而且——不是一个小问题——结果尊重数据……经过几个小时的试用,这说服了我购买优化工具箱。

问John或其他FEX老手一个简单的问题,通常被接受的引用FEX提交的方式是什么?

约翰内斯Korsawe

这真是一项伟大的工作。我发现它使用起来非常简单,而且效果非常好。再次谢谢你,约翰!

怎样才能最好地确定拟合线的不确定性或误差?

泽维尔泽维尔

约翰D 'Errico

戴夫,你在slmeval中发现了一个bug。我刚刚提交了修复。谢谢你告诉我这件事。

大卫Heslop

谢谢你,约翰,这是一个很棒的包,但我认为当使用样条曲线的逆函数时可能会有一个问题,它是单调递减的。

举个简单的例子,当我处理具有积极关系的数据时,一切都没问题:

首先要建立一种简单的积极关系
1) X =排序(randn(20日);
Y = X + 10;
slm = slmengine(X,Y,'plot','on');

%查找X=0.5的Y值
Yhat = slmeval (0.5, slm, 0);

并朝相反的方向努力
Xhat = slmeval (Yhat slm, 1)

Xhat =

0.5000

但是当我对负关系进行同样的尝试时,返回的是NaN:

%现在工作与负关系
1) X =排序(randn(20日);
Y = 10倍;
slm = slmengine(X,Y,'plot','on');

%查找X=0.5的Y值
slm Yhat = slmeval (0.5, 0)

并朝相反的方向努力
Xhat = slmeval (Yhat slm, 1)

Xhat =

当然,这只是一个简单的例子,我正在研究的问题涉及到更复杂的关系。也许我误解了slmeval的用法,但你能提供的任何建议都会很好,
谢谢你,戴夫

Juho Jalava

谢谢你,约翰,我对结果非常非常满意!

Raymond Cheng

谢谢楼主的分享。

詹姆斯

约翰D 'Errico

新版本刚刚上传,以修复更新的优化工具箱版本所产生的“活动集”问题。

克里斯·范德·托特

很好,约翰,我会在论文中引用你的。

我还收到了这样的警告:
警告:选项LargeScale = 'off'和算法= 'trust-region-reflective'冲突。
忽略算法和运行active-set方法。若要运行trust-region-reflective,请设置
LargeScale = 'on'。若要运行active-set而不出现此警告,请使用Algorithm = 'active-set'。

在slmengine的第158行之后添加这一行。m文件;
fminconoptions。算法= 'active-set';

现在我不再收到警告了。

约翰D 'Errico

fmincon返回的警告消息是新的,显然是由于优化工具箱中的更改。不过,这只是一个警告,不会影响代码本身的操作。

我会解决这个问题的。

迪迪Cvet


我认为这种工具箱是一个好主意,我正在对这个文件做一些测试。我有非常具体的数据点,在做我的实验时,我试图使用“结”,“自由”选项,但我得到这个警告信息:

警告:选项LargeScale = 'off'和算法= 'trust-region-reflective'冲突。
忽略算法和运行active-set方法。若要运行trust-region-reflective,请设置
LargeScale = 'on'。若要运行active-set而不出现此警告,请使用Algorithm = 'active-set'。

我试着加上这一行
> > fminconoptions。算法= 'Active-set';
在你的小引擎里。M代码,但它不起作用。

谢谢你剪这个!
最好的祝愿
Dijana

约翰D 'Errico

费边:这个更难解。通常,x(t)和y(t)是独立拟合的。然而,你的约束是在期限上

根号((dx/dt)²+ (dy/dt)²)

你需要三次结果吗?如果是这样,那么它就更复杂了,因为任何整体斜率类型的约束都足够糟糕,以至于可以用三次方程来表示。

我可能会使用蛮力方法。使用一对独立的模型,x(t) y(t)。你可以在这些模型上对dx/dt和dy/dt进行全局约束,限制得到的最大和最小斜率。

现在,回过头来,测试两条曲线在(x,y)平面上合并成参数路径时的实际速度。如果根号((dx/dt)^2 + (dy/dt)^2)没有超过速度极限,那么就完成了。否则,您现在需要使用fmincon来扰动样条的参数,同时将误差的全局平方和最小化到(x(t), y(t))。

它的约束条件显然是非线性的。您可以在每个点上设置一个约束,但这不会约束获得的真正最大速度。所以你可能在每条曲线上采样1000个点,沿着曲线返回1000个非线性约束。这将给你速度的必要条件,但它不一定是真正的充分条件。因此,它可能会超过目标最大速度一点点。

最后,在样条参数空间上的优化还会对这些参数有其他的线性约束。我想,当模型发送到lsqlin时,可以(如果您有胆量的话)深入到SLM代码中提取(并返回)用于估计模型的实际方程。Fmincon也需要使用这些约束。

HTH,
约翰

费边主义通过

亲爱的约翰,

我想知道你的函数是否有可能随着时间的推移将样条曲线拟合到一组(x,y)坐标(每个数据点也有一个相关的权重)。我想约束拟合的样条轨迹的速度,这意味着我不能单独拟合(x,t)和(y,t)如果您的SLM工具无法做到这一点,您对如何解决这个问题有什么建议吗?

谢谢,费边

Jeem79奥尔森

我刚刚用你的包来拟合我的图像采集和处理得到的应力-应变曲线,效果很好。谢谢你的出色工作!然而,是否可能只提取拟合的曲线?我在你的文档中没有看到一个明显的选项。

Jeem79

约书亚

约翰D 'Errico

Pete -我要尽快完成的一个目标是编写一个将SLM封装在里面的gui。注意,SLM中的计算工具称为SLMENGINE。这是有目的的,因为我的期望是,当我能够提供gui表单时,大多数用户会使用它。所以我一直在计划一个gui包装器。

即使这样,SLM也不允许您通过数据徒手绘制曲线,然后返回该曲线的系数。徒手绘制的曲线可能是任意复杂的,甚至不是单值函数。当您拟合曲线,然后应用您自己对要建模的系统的特殊知识(以对底层功能形式的总体形状的约束的形式)时,SLM是最好的。但是,要遵循的绘制曲线太宽泛了,无法遵循。所以在这种情况下,SLM通常无法返回这种功能形式。

这也是一个独特的问题。那么问题是找到符合原始数据的曲线,并且具有手绘曲线的一般形状吗?这涉及到两个独立的近似问题。似乎必须使用工具来平滑和近似绘制的曲线。然后用同样的工具试着通过数据拟合绘制的曲线?这项任务将花费大量的精力,并且在对用户透明的情况下永远不可能这样做。更糟糕的是,假设最后的曲线与数据不太吻合(正如用户所感知的那样?)不适合从何而来?是不是与手绘的曲线不太吻合?还是与数据本身不匹配?

皮特·谢尔

是否有可能添加GUI,这样用户就可以简单地拖动/调整他们想要的合适的线。然后,脚本返回调整行的函数形式和系数。也许作为一个额外的脚本或什么的。

彼得•西蒙

一个极好的包装。做得好!它非常适合拟合在轨测试(IOT)天线方向图测量数据点的曲线,用于验证我们的卫星天线的性能。非常感谢。

彼得•西蒙
空间系统/知识的
天线子系统操作

凌晨

S B

SLMtools / html /