将抛物线拟合到一组点的最快方法?

发布于 2024-09-29 10:13:49 字数 121 浏览 3 评论 0原文

给定一组点,将抛物线拟合到它们的最快方法是什么?是进行最小二乘计算还是有迭代的方法?

谢谢

编辑: 我认为梯度下降是可行的方法。最小二乘计算会更加繁重(必须进行 qr 分解或其他保持稳定的事情)。

Given a set of points, what's the fastest way to fit a parabola to them? Is it doing the least squares calculation or is there an iterative way?

Thanks

Edit:
I think gradient descent is the way to go. The least squares calculation would have been a little bit more taxing (having to do qr decomposition or something to keep things stable).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

痴者 2024-10-06 10:13:49

如果这些点没有关联的错误,您可以插入三个点。否则,最小二乘法或任何等效公式都是可行的方法。

If the points have no error associated, you may interpolate by three points. Otherwise least squares or any equivalent formulation is the way to go.

故事和酒 2024-10-06 10:13:49

我最近需要找到一条经过 3 个点的抛物线。

假设您有 (x1,y1)、(x2,y2) 和 (x3,y3) 并且您希望抛物线

y-y0 = a*(x-x0)^2

穿过它们:找到 y0、x0 和 a >。

你可以做一些代数并得到这个解决方案(假设点不都在一条线上):

let c = (y1-y2) / (y2-y3)
x0    = ( -x1^2 + x2^2 + c*( x2^2 - x3^2 ) )  /  (2.0*( -x1+x2 + c*x2 - c*x3 ))
a     = (y1-y2)  /  ( (x1-x0)^2 - (x2-x0)^2 )
y0    = y1 - a*(x1-x0)^2

注意在c的方程中if y2==y3然后你'有问题。所以在我的算法中,我检查这一点并将 x1, y1 与 x2, y2 交换,然后继续。

希望有帮助!

保罗·普罗伯特

I recently needed to find a parabola that passes through 3 points.

suppose you have (x1,y1), (x2,y2) and (x3,y3) and you want the parabola

y-y0 = a*(x-x0)^2

to pass through them: find y0, x0, and a.

You can do some algebra and get this solution (providing the points aren't all on a line) :

let c = (y1-y2) / (y2-y3)
x0    = ( -x1^2 + x2^2 + c*( x2^2 - x3^2 ) )  /  (2.0*( -x1+x2 + c*x2 - c*x3 ))
a     = (y1-y2)  /  ( (x1-x0)^2 - (x2-x0)^2 )
y0    = y1 - a*(x1-x0)^2

Note in the equation for c if y2==y3 then you've got a problem. So in my algorithm I check for this and swap say x1, y1 with x2, y2 and then proceed.

hope that helps!

Paul Probert

日记撕了你也走了 2024-10-06 10:13:49

计算解决方案几乎总是比迭代解决方案更快。 “例外”是迭代次数少和计算复杂。

我会使用最小二乘法。我只对它进行了线性回归拟合的编码,但它可以用于抛物线(我最近有理由查找它 - 来源包括旧版的“Numerical Recipes” Press et al; 和“Engineering Mathematics” Kreyzig)。

A calculated solution is almost always faster than an iterative solution. The "exception" would be for low iteration counts and complex calculations.

I would use the least squares method. I've only every coded it for linear regression fits but it can be used for parabolas (I had reason to look it up recently - sources included an old edition of "Numerical Recipes" Press et al; and "Engineering Mathematics" Kreyzig).

话少心凉 2024-10-06 10:13:49

抛物线算法

  1. 阅读编号:数据点 n 和多项式 Mp 的阶数。
  2. 读取数据值。
  3. 如果n<熔点
    [ 回归是不可能的 ]
    停止
    别的
    继续 ;
  4. 设M=Mp+1;
  5. 计算 C 矩阵的系数。
  6. 计算 B 矩阵的系数。
  7. 求解系数
    a1,a2,. 。 。 。 。 。 。一个 。
  8. 写出系数 。
  9. 估计自变量 glren 处的函数值。

ALGORITHM FOR PARABOLA

  1. Read no. of data points n and order of polynomial Mp .
  2. Read data values .
  3. If n< Mp
    [ Regression is not possible ]
    stop
    else
    continue ;
  4. Set M=Mp + 1 ;
  5. Compute co-efficient of C-matrix .
  6. Compute co-efficient of B-matrix .
  7. Solve for the co-efficients
    a1,a2,. . . . . . . an .
  8. Write the co-efficient .
  9. Estimate the function value at the glren of independents variables .
贪恋 2024-10-06 10:13:49

使用免费的任意精度数学程序“PARI”(适用于 Mac 或 PC):
以下是我如何将抛物线拟合到 641 个点的集合上,
我还展示了如何找到该抛物线的最小值:

  1. 设置高位数的精度:

    <前><代码>\p 300

  2. 将数据点写入文本文件,以空格分隔
    对于每个数据点
    (使用以十为基数的 ASCII 字符,文件开头或文件结尾处没有空格,并且没有回车符,写入极大或极小的浮点,例如
    “9.0E-23”但不是“9.0D-23”)。

  3. 创建一个字符串来指向该文件:

    fileone="./desktop/data.txt"
    
  4. 使用以下说明将该文件读入 PARI:

    fileopen(fileone,r)
    readsplit(文件) = my(cmd);cmd="perl -ne \"chomp;打印 '[' 。加入(',', split(/ +/)) 。 ']\n';\"";eval(externstr(Str(cmd," ",文件)))
    读取分割(文件一个) 
    
  5. 用名称标记该数据:

    <前><代码>中 = %
    V = 在[1]中

  6. 定义最小二乘拟合函数:

    lsf(X,Y,n) = my(M=matrix(#X,n+1,i,j,X[i]^(j-1)));fit=Polrev(matsolve) (M~*M,M~*Y~))
    
  7. 将该 lsf 函数应用于您的 641 个数据点:

    <前><代码>lsf([-320..320],V, 2)

  8. 然后,如果您想显示该抛物线拟合的最小值,请输入:

    xextreme=solve(x=-1000,1000,eval(deriv(fit)));print(xextreme*(124.5678-123.5678)/640+(124.5678+123.5678)/2);x=xextreme ;打印(评估(适合))

在上面的命令行中的“打印”语句之前,我必须调整特定的 x 轴缩放比例)。

Using the free arbitrary accuracy math program "PARI" (for Mac or PC):
Here is how I would fit a parabola to a set of 641 points,
and I also show how to find the minimum of that parabola:

  1. Set a high number of digits of precision:

    \p 300
    
  2. Write the data points to a text file separated by one space
    for each data point
    (use ASCII characters in base ten, no space at file start or file end, and no returns, write extremely large or small floating points as for example
    "9.0E-23" but not "9.0D-23" ).

  3. make a string to point to that file:

    fileone="./desktop/data.txt"
    
  4. read that file into PARI using the following instructions:

    fileopen(fileone,r)
    readsplit(file) = my(cmd);cmd="perl -ne \"chomp; print '[' . join(',', split(/ +/)) . ']\n';\"";eval(externstr(Str(cmd," ",file)))
    readsplit(fileone) 
    
  5. Label that data with a name:

    in = %
    V = in[1]
    
  6. Define a least squares fit function:

    lsf(X,Y,n) = my(M=matrix(#X,n+1,i,j,X[i]^(j-1)));fit=Polrev(matsolve(M~*M,M~*Y~))
    
  7. Apply that lsf function to your 641 data points:

    lsf([-320..320],V, 2)
    
  8. Then if you want to show the minimum of that parabolic fit, enter:

    xextreme = solve (x=-1000,1000,eval(deriv(fit)));print (xextreme*(124.5678-123.5678)/640+(124.5678+123.5678)/2);x=xextreme;print(eval(fit))
    

(I had to adjust for my particular x-axis scaling before the "print" statement in that command line above).

丿*梦醉红颜 2024-10-06 10:13:49

(注:为简化该算法而做出的牺牲
导致它只能工作
当数据集具有等距的 x 轴坐标时。)

我担心我的上一篇文章
太紧凑而难以跟随
很难转换到其他环境。
我想在这里展示如何解决
抛物线数据显式拟合的广义问题
没有专门的矩阵数学术语;
这样每个乘法、除法、
减法和加法可以同时看到。
为了节省墨水,此拟合将 x 轴重新参数化为均匀
以零为中心的间隔点
这样奇次幂总和就全部被消除
(节省大量空间和时间),
所以 N 个数据点的 x 坐标
由点有效标记
该向量的:X=[-(N-1)/2..(N-1)/2]。
例如将返回“xextreme”
与那些整数索引
所以(如果需要的话)一个简单的(消耗很少的CPU时间)
在以下算法之后必须应用线性变换
将其与问题的特定 x 轴标签进行比较。

这是用以下语言写的
免费程序“PARI”但所有
命令很容易翻译成任何语言。

步骤1:为y轴数据分配标签:

? V=[5,2,1,2,5]

"PARI" 确认该条目:

%280 = [5, 2, 1, 2, 5]

然后输入以下内容处理算法
计算最佳拟合抛物线
通过具有恒定 x 轴间隔的任何 y 轴数据集:


? g=#V;h=(g-1)*g*(g+1)/3;i=h*(3*g*g-7)/5;\
a=sum(i=1,g,V[i]);b=sum(i=1,g,(2*i-1-g)*V[i]);c=sum(i=1,g,(2*i-1-g)*(2*i-1-g)*V[i]);\
A=matdet([a,c;h,i])/matdet([g,h;h,i]);B=b/h*2;C=matdet([g,h;a,c])/matdet([g,h;h,i])*4;\
xextreme=-B/(2*C);yextreme=-B*B/(4*C)+A;fit=Polrev([A,B,C]);\
print("\n","y of extreme is ",yextreme,"\n","which occurs this many data points from center of data: ",xextreme)                                                                                       
                                                                          
(Note for non-PARI users:
the command "matdet([a,c;h,i])" 
is just another way of entering "a*i-c*h") 

然后这些命令会生成以下屏幕输出:

y of extreme is 1
从数据中心出现这么多数据点:0

该算法将拟合的多项式存储在变量“fit”中:(

? fit
%282 = x^2 + 1
?

请注意,为了使该算法简短
x 轴标签指定为 X=[-(N-1)/2..(N-1)/2],
因此它们是 X=[-2,-1,0,1,2]
为了纠正这个问题
对于与参数化相同的多项式
通过 x 轴坐标数据集 X=[−1,0,1,2,3]:
只需应用一个简单的线性变换,在本例中:
“x^2 + 1” --> “(t - 1)^2 + 1”。)

(Note: A sacrifice made to simplify this algorithm
causes it to work only
when the data set has equally spaced x-axis coordinates.)

I was worried that my last post
was too compact to follow and
too hard to convert to other environments.
I would like to show here how to solve the
generalized problem of parabolic data fitting explicitly
without specialized matrix math terminology;
and so that each multiplication, division,
subtraction and addition can be seen at once.
To save ink this fit reparameterizes the x-axis as evenly
spaced points centered on zero
so that odd powered sums all get eliminated
(saving a lot of space and time),
so the x-coordinates of the N data points
are effectively labeled by points
of this vector: X=[-(N-1)/2..(N-1)/2].
For example "xextreme" will be returned
versus those integer indices
and so (if desired) a simple (consumes very little CPU time)
linear transformation must be applied after the algorithm below
to get it versus your problem's particular x-axis labels.

This is written in the language of
the free program "PARI" but all the
commands are simple to translate to any language.

Step 1: assign a label to the y-axis data:

? V=[5,2,1,2,5]

"PARI" confirms that entry:

%280 = [5, 2, 1, 2, 5]

Then type in the following processing algorithm
which calculates a best fit parabola
through any y-axis data set with constant x-axis separation:


? g=#V;h=(g-1)*g*(g+1)/3;i=h*(3*g*g-7)/5;\
a=sum(i=1,g,V[i]);b=sum(i=1,g,(2*i-1-g)*V[i]);c=sum(i=1,g,(2*i-1-g)*(2*i-1-g)*V[i]);\
A=matdet([a,c;h,i])/matdet([g,h;h,i]);B=b/h*2;C=matdet([g,h;a,c])/matdet([g,h;h,i])*4;\
xextreme=-B/(2*C);yextreme=-B*B/(4*C)+A;fit=Polrev([A,B,C]);\
print("\n","y of extreme is ",yextreme,"\n","which occurs this many data points from center of data: ",xextreme)                                                                                       
                                                                          
(Note for non-PARI users:
the command "matdet([a,c;h,i])" 
is just another way of entering "a*i-c*h") 

Those commands then produce the following screen output:

y of extreme is 1
which occurs this many data points from center of data: 0

The algorithm stores the polynomial of the fit in the variable "fit":

? fit
%282 = x^2 + 1
?

(Note that to make that algorithm short
the x-axis labels are assigned as X=[-(N-1)/2..(N-1)/2],
thus they are X=[-2,-1,0,1,2]
To correct that
for the same polynomial as parameterized
by an x-axis coordinate data set of say X=[−1,0,1,2,3]:
just apply a simple linear transform, in this case:
"x^2 + 1" --> "(t - 1)^2 + 1".)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文