# spaps
平滑样条曲线
函数库: TyCurveFitting
# 语法
sp, values, rho = spaps(x,y,tol)
_ = spaps(x,y,tol,w,m)
_ = spaps((x1,...,xr),y,tol,___)
# 说明
sp, values, rho = spaps(x, y, tol) 以 B 型返回与给定点 (x[j],y[:,j]),j=1:length(x) 相差在给定容度 tol 以内最平滑的曲线 f,光滑值 values 以及实际使用的
数据值 y[:,j] 为可以为标量、向量、矩阵或者多维数组。位于同一数据网格中的数据点将被其加权均值替代,其权为对应权的和,容度 tol 也会相应减少。
values 与 fnval(sp,x) 相同。此处曲线 f 与给定数据之间的距离为
其中权 w 默认选为使得 E(f) 为对
最光滑意味着下述粗糙测度的最小化
其中
当 tol 为非负值时,样条 f 为使得
粗糙度量中的权函数
_ = spaps(x, y, tol, w, m) 让您决定权向量 w 以及/或者整数 m,此通过输入参数完成。对于这种用法,w 必须为与 x 相同长度的非负向量,m 必须为 1(表示分段线性光滑样条)、2(表示默认的三次光滑样条)或 3(表示五次光滑样条)。
如果结果的光滑样条 sp 需要在其基本区间以外求值,则需使用 fnxtr(sp, m) 来替代,以保证在基本区间以外,其 m 阶导数为 0。
_ = spaps((x1,...,xr), y, tol, ___)以 B 形式返回有 r 个变元的张量光滑样条,该样条与给定网格值大体在容度内。对于散点值,请使用 tpaps。现在 y 应给定对应的网格值,其中 size(y) 在 f 返回标量时与 (length(x1),...,length(xr)) 相同,在 f 返回 d 向量时与 (d,length(x1),...,length(xr)) 相同。tol 必须为有 r 个元素的元组,其中 tol[i] 表示在第 i 步,即对第 i 个变元构造单变元(返回向量)光滑样条,时使用的容度。可选输入 m 必须为 r 向量(其中每个元素必须为 1、2 或 3),可选输入 w 必须为长为 r 的元组,其中 w[i] 要么空(表示选择默认值)要么为与 xi 相同长度的正向量。示例
# 示例
来自噪声数据的两条三次光滑样条的比较
该代码返回对与非噪声数据足够接近的噪声数据的拟合,因为前者来源于一个变化很慢的函数,也因此使用的 TOL 的维数与噪声的维数相匹配。
using TyCurveFitting
using TyPlot
using TyMath
rng = MT19937ar(5489)
x = LinRange(0, 2 * pi, 21)'
y = sin.(x) .+ (rand(rng, 1, 21) .- 0.5) .* 0.2
sp, = spaps(x, y, (0.05)^2 * (x[end] - x[1]))
fnplt(sp)
该代码使用了与之前相同的数据与容度,但在区间右半使粗糙权仅为 0.1,这相对应地构造了更为粗糙但也更好的拟合。
sp1, = spaps(x, y, [(0.025)^2 * (x[end] - x[1]) ones(1, 10) repeat([0.1], 1, 10)])
fnplt(sp1)
最后,将之前的得到的两条三次光滑样条作比较。
fnplt(sp)
hold("on")
fnplt(sp1, "r")
plot(x, y, "ok")
hold("off")
title("Two cubic smoothing splines")
xlabel("The red one has reduced smoothness requirement in right half.")

对二元函数的噪声数据的光滑逼近
这个例子构造了对光滑二元函数的噪声的光滑逼近。注意 ndgrid 的使用,如果使用 meshgrid2 则会报错。
using TyCurveFitting
using TyBase
using TyMath
x = -2:0.2:2
y = -1:0.25:1
xx, yy = ndgrid(x, y)
rng = MersenneTwister(1234)
z = exp.(-(xx .^ 2 + yy .^ 2)).+ (rand(rng,size(xx))-.5)/30
sp, = spaps((x, y), z, 8 / (60^2))
fnplt(sp)

# 输入参数
x - 数据位点向量 | 数组元组
需要拟合的数据值 y 的数据位点,对单变元指定为一维矩阵,对于多变元字段为元组。样条 f 使得对于每一个数据位点 x 其节点满足对于所有的j,f(x[j])=y[:,j]。
对多变元、网格数据,可以指定 x 为指定每个变元维度的数据位点的元组:f(x1[i],x2[j],...,xn[k])=y[:,i,j,...,k]。
数据类型: Int | Float
y - 拟合数据向量 | 矩阵 | 多维数组
在样条构造中需要拟合的数据值,指定为一维矩阵或多维数组。数据值 y[:,j] 可以为标量、矩阵或者 n 维数组。在相同位点 x 中给出的数据值将会被平均。
数据类型: Int | Float
tol - 容度标量
给定数据点的容度,由标量表示。
数据类型: Float
w - 数据权向量 | 数组元组
数据点的权 w,指定为与 x 相同长度的、元素非负的向量。
数据类型: Int | Float
m - 微分阶数标量
微分阶数,指定为标量。该值必须为 1,表示分段线性光滑样条,2,表示默认的三次光滑样条,或 3,表示五次光滑样条。
数据类型: Int
# 输出参数
sp - B 样条样条结构体
样条,以有以下元素的结构体形式返回。
Form - 样条的类型"B-"
样条的类型,返回为 "B-",这意味着样条为 B 型。
数据类型: String
Knots - 样条节点的位置向量 | 数组元组
样条的节点位置,单变元时以向量,多变元时以向量元组形式返回。其中向量含有严格增的元素,分别表示定义多项式片段的定义区间的左右端点。
数据类型: Int | Float
Coefs - 多项式系数矩阵 | 数组
每个片段的多项式系数,单变元时以矩阵,多变元时以数组形式返回。
数据类型: Int | Float
Number - 多项式片段的数目标量 | 向量
描述样条的多项式片段的数目,单变元时以标量,多变元时以由各变元的多项式片段的数目组成的向量形式返回。
数据类型: Int
Order - 多项式阶数标量 | 向量
描述样条的分段多项式的阶数,单变元时以标量,多变元时以各变元阶数组成的向量形式返回。
数据类型: Int
Dim - 维数标量
目标函数的维数,以标量形式返回。
数据类型: Int
values - 计算值向量 | 矩阵 | 多维数组
样条在 x 中的点的值,单变元时以向量,多变元时以矩阵或数组形式返回。
数据类型: Int | Float
rho - 光滑参数标量 |数组元组
计算样条时使用的光滑参数,单变元时以标量,多变元时以标量值元组形式返回。
数据类型: Float
# 算法
该函数使用 Reinsch 的方法[1],包括他对最优光滑参数生成方程的选择,该选择会保证存在可用的好的初值且 Newton 法能够而且很快地收敛。
# 参考文献
[1] C. Reinsch. "Smoothing by spline functions." Numerical Math. 10, 1967(177-183).