You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/common.jl
+2Lines changed: 2 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -84,6 +84,8 @@ this will use weighted linear least squares. That is, the norm of
84
84
using their squares: for a number use `w^2`, for a vector `wᵢ^2`, and for a matrix
85
85
specify `W'*W`. This behavior may change in the future.)
86
86
87
+
For fitting with a large degree, the Vandermonde matrix is exponentially ill-conditioned. The [`ArnoldiFit`](@ref) type introduces an Arnoldi orthogonalization that fixes this problem.
## More accurate fitting for higher degree polynomials
349
+
350
+
"""
351
+
polyfitA(x, y, n=length(x)-1; var=:x)
352
+
fit(ArnoldiFit, x, y, n=length(x)-1; var=:x)
353
+
354
+
Fit a degree ``n`` or less polynomial through the points ``(x_i, y_i)`` using Arnoldi orthogonalization of the Vandermonde matrix.
355
+
356
+
The use of a Vandermonde matrix to fit a polynomial to data is exponentially ill-conditioned for larger values of ``n``. The Arnoldi orthogonalization fixes this problem.
357
+
358
+
# Returns
359
+
360
+
Returns an instance of `ArnoldiFit`. This object can be used to evaluate the polynomial. To manipulate the polynomial, the object can be `convert`ed to other polynomial types, though there may be some loss in accuracy when doing polynomial evaluations afterwards for higher-degree polynomials.
361
+
362
+
# Citations:
363
+
364
+
The two main functions are translations from example code in:
365
+
366
+
*VANDERMONDE WITH ARNOLDI*;
367
+
PABLO D. BRUBECK, YUJI NAKATSUKASA, AND LLOYD N. TREFETHEN;
maximum(abs, p(x) - f(x) for x ∈ range(-1,stop=1,length=500)) # 3.304586010148457e16
378
+
maximum(abs, q(x) - f(x) for x ∈ range(-1,stop=1,length=500)) # 1.1939520722092922e-7
379
+
380
+
N = 250; xs = [cos(j*pi/N) for j in N:-1:0];
381
+
p = fit(Polynomial, xs, f.(xs));
382
+
q = fit(ArnoldiFit, xs, f.(xs));
383
+
maximum(abs, p(x) - f(x) for x ∈ range(-1,stop=1,length=500)) # 3.55318186254542e92
384
+
maximum(abs, q(x) - f(x) for x ∈ range(-1,stop=1,length=500)) # 8.881784197001252e-16
385
+
386
+
p = fit(Polynomial, xs, f.(xs), 10); # least-squares fit
387
+
q = fit(ArnoldiFit, xs, f.(xs), 10);
388
+
maximum(abs, q(x) - p(x) for x ∈ range(-1,stop=1,length=500)) # 4.6775083806238626e-14
389
+
Polynomials.norm(q-p, Inf) # 2.2168933355715126e-12 # promotes `q` to `Polynomial`
390
+
```
391
+
392
+
"""
393
+
functionpolyfitA(x, y, n=length(x)-1; var=:x)
394
+
m =length(x)
395
+
T =eltype(y)
396
+
Q =ones(T, m, n+1)
397
+
#H = UpperHessenberg(zeros(T, n+1, n))
398
+
H =zeros(T, n+1, n)
399
+
400
+
q =zeros(T, m)
401
+
402
+
@inboundsfor k =1:n
403
+
q .= x .* Q[:,k]
404
+
for j in1:k
405
+
λ =dot(Q[:,j], q)/m
406
+
H[j,k] = λ
407
+
q .-= λ * Q[:,j]
408
+
end
409
+
H[k+1,k] =norm(q)/sqrt(m)
410
+
Q[:,k+1] .= q/H[k+1,k]
411
+
end
412
+
d = Q \ y
413
+
ArnoldiFit(d, H, var)
414
+
end
415
+
416
+
functionpolyvalA(d, H::AbstractMatrix{S}, s::T) where {T, S}
417
+
R =promote_type(T,S)
418
+
n =length(d) -1
419
+
W =ones(R, n+1)
420
+
@inboundsfor k in1:n
421
+
w = s .* W[k]
422
+
for j in1:k
423
+
w -= H[j,k] * W[j]
424
+
end
425
+
W[k+1] = w/H[k+1,k]
426
+
end
427
+
sum(W[i]*d[i] for i ineachindex(d))
428
+
end
429
+
430
+
# Polynomial Interface
431
+
"""
432
+
ArnoldiFit
433
+
434
+
A polynomial type produced through fitting a degree ``n`` or less polynomial to data ``(x_1,y_1),…,(x_N, y_N), N ≥ n+1``, This uses Arnoldi orthogonalization to avoid the exponentially ill-conditioned Vandermonde polynomial. See [`Polynomials.polyfitA`](@ref) for details.
0 commit comments