Thank your for your answer.
My input is a vector of size 16 containing values evenly distributed in the interval on which I want to approximate 1/sqrt(x). I tested my code with many different lower bounds, upper bounds and polynomial degrees. My function “GetMultDepth” in the code below takes as input the polynomial degree and outputs the corresponding multiplicative depth, according to the table given in FUNCTION_EVALUATION.md. I put two output examples below the code.
Here is a code example:
CCParams<CryptoContextCKKSRNS> parameters;
parameters.SetSecurityLevel(HEStd_128_classic);
#if NATIVEINT == 128 && !defined(__EMSCRIPTEN__)
ScalingTechnique rescaleTech = FIXEDAUTO;
usint dcrtBits = 78;
usint firstMod = 89;
#else
ScalingTechnique rescaleTech = FLEXIBLEAUTO;
usint dcrtBits = 59;
usint firstMod = 60;
#endif
parameters.SetScalingModSize(dcrtBits);
parameters.SetScalingTechnique(rescaleTech);
parameters.SetFirstModSize(firstMod);
uint32_t polyDegree = 27;
uint32_t multDepth = GetMultDepth(polyDegree);
parameters.SetMultiplicativeDepth(multDepth);
CryptoContext<DCRTPoly> cc = GenCryptoContext(parameters);
cc->Enable(PKE);
cc->Enable(KEYSWITCH);
cc->Enable(LEVELEDSHE);
cc->Enable(ADVANCEDSHE);
auto keyPair = cc->KeyGen();
cc->EvalMultKeyGen(keyPair.secretKey);
double lowerBound = 0.5;
double upperBound = 2;
std::vector<std::complex<double>> input = {0.5, 0.59375, 0.6875, 0.78125, 0.875, 0.96875, 1.0625, 1.15625, 1.25, 1.34375, 1.4375, 1.53125, 1.625, 1.71875, 1.8125, 1.90625};
size_t encodedLength = input.size();
Plaintext plaintext = cc->MakeCKKSPackedPlaintext(input);
auto ciphertext = cc->Encrypt(keyPair.publicKey, plaintext);
auto result = cc->EvalChebyshevFunction([](double x) -> double { return 1/std::sqrt(x); }, ciphertext, lowerBound, upperBound, polyDegree);
Plaintext plaintextDec;
cc->Decrypt(keyPair.secretKey, result, &plaintextDec);
plaintextDec->SetLength(encodedLength);
std::vector<std::complex<double>> finalResult = plaintextDec->GetCKKSPackedValue();
std::cout << "Actual output\n\t" << finalResult << std::endl << std::endl;
Here are two output examples.
Firstly on the interval [1,2] with polynomial degree 13 and multiplicative depth 5:
[ (-3,0) (-3.02987,0) (-3.05718,0) (-3.08236,0) (-3.10558,0) (-3.12712,0) (-3.14721,0) (-3.16595,0) (-3.18354,0) (-3.19999,0) (-3.21555,0) (-3.23021,0) (-3.24407,0) (-3.25721,0) (-3.26972,0) (-3.28159,0) ]
Secondly on the interval [0.7, 2] with polynomial degree 27 and multiplicative depth 6:
[ (3.32128,0) (4.30869,0) (7.45238,0) (6.84932,0) (5.26606,0) (4.5096,0) (6.86303,0) (3.74379,0) (5.10435,0) (6.02175,0) (5.73903,0) (5.68307,0) (6.63103,0) (4.47987,0) (7.11322,0) (8.08926,0) ]
Thanks a lot for your help.