I was wondering if there is a way to eval a polynomial under chebyshev basis without performing a linear transformation 1+2(x-a)/(b-a), or in general without taking into account any range.
For instance, there is the ‘classical’ EvalPoly function that takes as input ciphertext+coefficients. For chebyshev basis, there is no such thing, as EvalChebyshevSeries takes as input ciphertext+coefficients+[a,b] range. Is there a specific reason for that?
The Chebyshev interpolation is designed to work when the input is in the range [-1,1]. When the input is in a range [a,b], it first need to be scaled to [-1,1]. If you want to supply your own coefficients for the Chebyshev basis (this is defined over [-1,1]) just give as arguments a=-1, b=1.
Ok thank you, my doubt was w.r.t. the function itself. I know that such range is used to compute the coefficients (e.g., in EvalChebyshevFunction) but once these coefficients are computed, what is the role of a,b ?
In other words, once I have the set of coeffs, why should I use different values from a=-1 and b=1? What is the use case?
Computing the coefficients only describes the function, presumably you also need to evaluate the interpolation over an input of interest. Therefore, you need to ensure that the input is in the right range when you compute the interpolation, which means scaling it from [a,b] to [-1,1].
I am trying to port a Julia code (in plaintext) to a CKKS circuit. Unluckily I got stuck at the evaluation of some Chebyshev polynomials. I defined a minimal example to replicate the issue I am encountering as follows (hope is not a dumb error by my side:p)
Julia code:
using Polynomials
# This defines 1*T_0(x) + 2*T_1(x) + 3*T_2(x)
poly = ChebyshevT([1, 2, 3])
# Evaluates the polynomial in x=0.1
poly(0.1)
→ ans: -1.74
poly(0.2)
→ ans: -1.3599999999999999
On the other hand, if I try to evaluate the same polynomial under CKKS, I obtain the following
You should first do some sanity checks to ensure that the basis polynomials are defined in the same way in your Julia code and in the OpenFHE implementation. It’s a good idea to check the code and comments, but a simple way to check would be to also evaluate only T_0(x), only T_1(x) etc.
It is common for the zero-th basis coefficient to be written as a_0/2. So I tried EvalChebyshevSeries(c, \{2, 2, 3\}, -1, 1) instead of EvalChebyshevSeries(c, \{1, 2, 3\}, -1, 1); and I got -1.74, -1.36.
Thank you!! Indeed by using a_0 \cdot 2 I was able to obtain the result. Did not know about the common practice of writing a_0 as a_0 / 2… I wonder if it could be helpful to state that in the documentation of that (public) function (i.e., in here)
The link in the readme for function evaluation in OpenFHE FUNCTION_EVALUATION.md shows the convention used. Moreover, this is described for the method of computing the Chebyshev coefficients for a function in chebyshev.h.