Change History (16)
comment:1 by , 21 years ago
| Cc: | added |
|---|---|
| Summary: | psRandom problems → vectorBinDisect32 problems |
comment:2 by , 21 years ago
comment:3 by , 21 years ago
| Owner: | changed from to |
|---|
comment:4 by , 21 years ago
The function psVectorFitPolynomial1D() is failing for this reason: when asked
to fit a Chebyshev polynomial to the x and y vectors, it assumes that the values
of the x vector span the range [-1.0:1.0]. In your test code, the x vector
spans the range [-0.5:0.4].
At present, I'm looking into how the current algorithm for deriving the
Chebyshev coefficients can be modified so that those x values need not fully
span the [-1.0:1.0] interval.
In the meantime, is it possible for you to modify your application so that the x
vectors are defined over the [-1.0:1.0] range?
comment:5 by , 21 years ago
Can't we treat the data over the range [-1,-0.5] and [0.5,1] as bad? Why is it
essential to have data over the entire range [-1,1] to fit a polynomial?
comment:6 by , 21 years ago
I used Chebyshev polynomials before spanning the same range [-0.5:0.4] and had
no problems there. I've used them to test psPolynomial1DEval(),
psPolynomial1DEvalVector(), and psVectorFitPolynomial1D() but left those tests
out of the code before. I can post those as well if you'd like.
comment:8 by , 21 years ago
It's certainly possible to use Chebyshev polynomials over a range other than
[-1.0;1.0]. However, it's a tad difficult with our current framework for psLib.
For example, it's easy to scale the x-vector to [-1.0:1.0] upon entry to the
Chebyshev fitting routines. I've tried this, and it works. However, doing so
requires that the polynomial evaluation routines to scale the x-value as well.
And in order to do so, that routine would need to know the original range of the
x-vector: the problem is that, currently, there's no way to pass the original
range of the x-vector to the polynomial eval routine.
Here's one solution: create 2 private members of the polynomial struct called
->min and ->max. They refer to the original range of the x-vector when the
Chebyshev coefficients were derived, and they are set by the VectorFitPolynomial
routines as well. Then, when the polynomial eval routines are called, they
simply scale the x-value to [-1.0:1.0] based on those ->min and ->max members.
How does that sound?
Disclaimer: I am by no means and expert on this and I could easily be missing a
much simpler and obvious solution.
comment:9 by , 21 years ago
I think you want to use the standard, linear fitting method: generate the
matrix, invert, multiply. Otherwise, you're not using all the data.
comment:10 by , 21 years ago
| bug_group: | → PSLib? |
|---|
I'm not aware of a linear fitting method for Chebyshev polynomials (although I
know what that is for regular polynomials). Do you have a reference?
The current algorithm exploits the fact that Chebyshev polynomials are
orthogonal and at specific points (the Chebyshev nodes) in the [-1:1]
interval, they are either 0, 1, or -1. We calculate the coefficients based on
the function values at those points.
comment:11 by , 21 years ago
It's good to use the orthogonal property, but that means throwing away some of
the data --- by interpolating to pre-defined points, you're not using all the
data. This is not acceptable.
Please use the same algorithm as for the ordinary polynomials.
comment:12 by , 21 years ago
This is the exact algorithm used in Numerical Recipes. The interpolation is
necessary since we're fitting the polynomials to predetermined data points,
not approximating a known function.
I can first fit an ordinary polynomial to the data, and then derive the
coefficients of the Chebyshev polynomials. This seems very odd to me.
However, if you make that a documented requirement, I can do it.
comment:13 by , 21 years ago
No, I mean use the same algorithm as for the ordinary polynomials (i.e.,
generate the least squares matrix and vector, invert the matrix, multiply by the
vector), but solve for the Chebyshev polynomial coefficients. That is, instead
of constructing the matrix using ordinary polynomials, you do it using the
Chebyshev polynomials.
Interpolating is not an option, since it throws away data.
comment:14 by , 20 years ago
| Resolution: | → fixed |
|---|---|
| Status: | new → closed |
I implemented the least squares matrix and inverted the matrix. This worked.
However, it's CPU-intensive.
A faster algorithm is this. Simply fit an ordinary polynomial to the data,
then "reverse-engineer" those coefficients to determine the Chebyshev
coefficients: basically, for each c_0xi term in the ordinary polynomial, we
derive a linear set of equations based on all the xi terms in all the
component Cheby polynomials, and then solve this set of equations to determine
the Chebyshev coefficients. This set of equations is already in
upper-triangular form so it's inexpensive to solve. This method is in the
current CVS tree.
One last note: I'd still like to keep the older method for deriving the Cheby
coefficients in the code in a commented-out form. The reason is that I
anticipate someone, later on, beginning a discussion that starts like this:
"Why bother using Chebyshev polys if in order to calculate their coefficients
we first have to derive the ordinary polynomial? Shouldn't we simply use the
ordinary polynomial instead?" The answer, I believe, is that you might use
the Chebyshev polys when you want a much faster algorithm for deriving them,
though you'll sacrifice a little accuracy. The older method provides that.
comment:15 by , 20 years ago
| Keywords: | VERIFIED added |
|---|
vectorFitPolynomial1DChebyFast should never be used, unless the input data is
regularly distributed and not masked (rare, if ever).
The "slow" implementation is the correct one. Could you please optimise it by:
- Using psPolynomial1DEvalVector within a loop on the polynomials instead of
evaluating inside a double loop.
- Calculating A and B in the same loop
- Using the fact that the least squares matrix is symmetric, so that only ~ 1/2
the calculations are required.

sorry this was blank at first...
I'm running some psLib testing code on rma and I'm getting a warning I don't
think I should be getting. First, here's the code:
========================================
#include <stdio.h>
#include <math.h>
#include "pslib_strict.h"
#include "psTest.h"
static psS32 testVectorFitPolynomial1D_01(void);
/* list of test functions in test suite */
testDescription tests[] = {
{testVectorFitPolynomial1D_01,2,"psVectorFitPolynomial1D_01",0,false},
/* basic main function: just need to define the test suite name */
int main(int argc, char* argv[])
{
}
# define X0 +5.0
# define X1 +3.0
# define X2 -1.0
# define X3 -2.0
static psPolynomial1D *makePolynomial1D(int Nord, psPolynomialType type) {
}
static void fillVectors(psVector *x, psVector *y, int Nord, int Npts,
psPolynomialType type) {
}
# define NPTS 10
int testVectorFitPolynomial1D_01(void) {
poly->coeff[%d]=%.20f\n",i,polycopy->coeff[i],i,poly->coeff[i]);
poly->coeffErr[%d]=%.20f\n",i,polycopy->coeffErr[i],i,poly->coeffErr[i]);
NORD=%d\n", nBad, NORD);
}
===============================================
here's one of the warnings it's giving me:
rma |W|vectorBinDisectF32
0.400000).
This only happens in the second loop over k where the polynomial type is
PS_POLYNOMIAL_CHEB.