# How to evaluate approximate 1/x function with high precision

**URL:** <https://openfhe.discourse.group/t/how-to-evaluate-approximate-1-x-function-with-high-precision/967>\
**Category:** Library Questions\
**Created:** [December 9, 2023, 7:37pm UTC](https://openfhe.discourse.group/t/how-to-evaluate-approximate-1-x-function-with-high-precision/967 "2023-12-09T19:37:30Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![oksuman](https://avatars.discourse-cdn.com/v4/letter/o/6de8d8/32.png) [@oksuman](https://openfhe.discourse.group/u/oksuman)\
**Post date:** [December 9, 2023, 7:37pm UTC](https://openfhe.discourse.group/t/how-to-evaluate-approximate-1-x-function-with-high-precision/967/1 "2023-12-09T19:37:30Z")

</div>

Hello,  
I’m attempting to evaluate the 1/x function on ciphertext.  
I’ve used the EvalDivide() function from the library, but the results seem to have some errors.  
Could you please review my code to see if there are any issues with how I’m using this function?

This is the code.

```auto
void EvalFunctionExample() {
    CCParams<CryptoContextCKKSRNS> parameters;

    parameters.SetSecurityLevel(HEStd_NotSet);
    parameters.SetRingDim(1 << 10);
#if NATIVEINT == 128
    usint scalingModSize = 78;
    usint firstModSize = 89;
#else
    usint scalingModSize = 50;
    usint firstModSize = 60;
#endif
    parameters.SetScalingModSize(scalingModSize);
    parameters.SetFirstModSize(firstModSize);

    uint32_t polyDegree = 50;
    uint32_t multDepth = 10;

    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);

    std::vector<double> input{1,2,3,4} ;
    size_t encodedLength = input.size();
    Plaintext plaintext = cc->MakeCKKSPackedPlaintext(input);
    auto ciphertext = cc->Encrypt(keyPair.publicKey, plaintext);

    double lowerBound = 0;
    double upperBound = 5;

    auto result = cc->EvalDivide(ciphertext, lowerBound, upperBound, polyDegree);

    Plaintext plaintextDec;
    cc->Decrypt(keyPair.secretKey, result, &plaintextDec);
    plaintextDec->SetLength(encodedLength);

    std::vector<double> finalResult = plaintextDec->GetRealPackedValue();
    std::cout << "Actual output\n\t" << finalResult << std::endl << std::endl;
}

```

This is the result.  
 ![image](https://canada1.discourse-cdn.com/flex031/uploads/openfhe/original/1X/1011501f409a0fa2bc40a36713b448eb72db313e.png)

Additionally, I’d like to learn how to achieve accurate evaluations of the 1/x function on ciphertext. Furthermore, I’m curious about the meaning of the upperbound parameter in the EvalDivide() function. Can this parameter have a large value, such as 100 or above?

Thank you for reading.

---

<div class="post-metadata">

**Author:** ![narger](https://yyz1.discourse-cdn.com/flex031/user_avatar/openfhe.discourse.group/narger/32/420_2.png) [@narger](https://openfhe.discourse.group/u/narger)\
**Post date:** [December 11, 2023, 11:04am UTC](https://openfhe.discourse.group/t/how-to-evaluate-approximate-1-x-function-with-high-precision/967/2 "2023-12-11T11:04:03Z")

</div>

By setting the bounds to [1, 4] you will get almost perfect results:

```auto
Actual output
	[1 0.5 0.333333 0.25]

```

Of course, encode your values in a four-slots plaintexts:

```auto
Plaintext plaintext = cc->MakeCKKSPackedPlaintext(input,1, 0, nullptr, 4);

```

Otherwise you would have a lot of zeros, which are not included in your interval.

In order to understand why this happens, think about 1 /x near zero:

![y-1-x](https://canada1.discourse-cdn.com/flex031/uploads/openfhe/original/1X/5730aad6518df695b32bc2116a38073a12bf2eab.png)

Using polynomials to approximate that interval is really a hard problem, also because that function does not even exist in 0!  
If you instead approximate it starting from 1 (or maybe also from 0.2/0.3, something like that) you will have less issues for sure.
