1 /* Copyright (C) 2012-2020 IBM Corp.
2  * This program is Licensed under the Apache License, Version 2.0
3  * (the "License"); you may not use this file except in compliance
4  * with the License. You may obtain a copy of the License at
5  *   http://www.apache.org/licenses/LICENSE-2.0
6  * Unless required by applicable law or agreed to in writing, software
7  * distributed under the License is distributed on an "AS IS" BASIS,
8  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9  * See the License for the specific language governing permissions and
10  * limitations under the License. See accompanying LICENSE file.
11  */
12 #ifndef HELIB_NORMS_H
13 #define HELIB_NORMS_H
14 /**
15  * @file norms.h - computing various norms of ring elements
16  **/
17 #include <vector>
18 #include <complex>
19 #include <NTL/ZZX.h>
20 #include <NTL/xdouble.h>
21 //#include <NTL/RR.h>
22 #include <helib/zzX.h>
23 
24 namespace helib {
25 
26 class DoubleCRT;
27 
28 long sumOfCoeffs(const zzX& f);          // = f(1)
29 NTL::ZZ sumOfCoeffs(const NTL::ZZX& f);  // = f(1)
30 NTL::ZZ sumOfCoeffs(const DoubleCRT& f); // somewhat lame implementation
31 
32 //! The L-infinity norm of an element (in coefficient representation)
33 template <typename T>
largestCoeff(const NTL::Vec<T> & f)34 double largestCoeff(const NTL::Vec<T>& f)
35 {
36   double mx = 0;
37   for (auto& x : f) {
38     auto sz = abs(x);
39     if (mx < sz)
40       mx = NTL::conv<double>(sz);
41   }
42   return mx;
43 }
44 template <typename T>
largestCoeff(const std::vector<T> & f)45 double largestCoeff(const std::vector<T>& f)
46 {
47   double mx = 0;
48   for (auto& x : f) {
49     auto sz = abs(x);
50     if (mx < sz)
51       mx = NTL::conv<double>(sz);
52   }
53   return mx;
54 }
55 
56 NTL::ZZ largestCoeff(const NTL::ZZX& f);
57 
58 NTL::ZZ largestCoeff(const NTL::Vec<NTL::ZZ>& f);
59 // somebody eliminated this...please leave it here!
60 
61 NTL::ZZ largestCoeff(const DoubleCRT& f);
62 
63 //! The L2-norm of an element (in coefficient representation)
64 double coeffsL2NormSquared(const zzX& f);             // l2 norm^2
65 NTL::xdouble coeffsL2NormSquared(const NTL::ZZX& f);  // l2 norm^2
66 NTL::xdouble coeffsL2NormSquared(const DoubleCRT& f); // l2 norm^2
67 
coeffsL2Norm(const zzX & f)68 inline double coeffsL2Norm(const zzX& f) // l2 norm
69 {
70   return sqrt(coeffsL2NormSquared(f));
71 }
coeffsL2Norm(const NTL::ZZX & f)72 inline NTL::xdouble coeffsL2Norm(const NTL::ZZX& f) // l2 norm
73 {
74   return sqrt(coeffsL2NormSquared(f));
75 }
coeffsL2Norm(const DoubleCRT & f)76 inline NTL::xdouble coeffsL2Norm(const DoubleCRT& f) // l2 norm
77 {
78   return sqrt(coeffsL2NormSquared(f));
79 }
80 
81 typedef std::complex<double> cx_double;
82 
83 //! Computing the L-infinity norm of the canonical embedding
84 //! Assumed: deg(f) < phi(m).
85 double embeddingLargestCoeff(const zzX& f, const PAlgebra& palg);
86 
87 double embeddingLargestCoeff(const std::vector<double>& f,
88                              const PAlgebra& palg);
89 
90 // computes two for the price of one
91 void embeddingLargestCoeff_x2(double& norm1,
92                               double& norm2,
93                               const std::vector<double>& f1,
94                               const std::vector<double>& f2,
95                               const PAlgebra& palg);
96 
97 NTL::xdouble embeddingLargestCoeff(const NTL::ZZX& f, const PAlgebra& palg);
98 
99 //! Computes canonical embedding.
100 //! Requires p==-1 and m==2^k where k >=2 and f.length() < m/2.
101 //! Sets v[m/4-1-i] = DFT[palg.ith_rep(i)] for i in range(m/4),
102 //! where DFT[j] = f(W^j) for j in range(m), and W = exp(-2*pi*I/m).
103 // FIXME: need to to understand and document why te v array
104 // gets initialized in the order that it does...what else
105 // in the library depends on this particular order.
106 void CKKS_canonicalEmbedding(std::vector<cx_double>& v,
107                              const zzX& f,
108                              const PAlgebra& palg);
109 
110 void CKKS_canonicalEmbedding(std::vector<cx_double>& v,
111                              const NTL::ZZX& f,
112                              const PAlgebra& palg);
113 
114 void CKKS_canonicalEmbedding(std::vector<cx_double>& v,
115                              const std::vector<double>& f,
116                              const PAlgebra& palg);
117 
118 //! Requires p==-1 and m==2^k where k >=2.
119 //! Computes the inverse of canonical embedding, scaled by scaling
120 //! and then rounded to nearest integer.
121 void CKKS_embedInSlots(zzX& f,
122                        const std::vector<cx_double>& v,
123                        const PAlgebra& palg,
124                        double scaling);
125 
126 } // namespace helib
127 
128 #endif // ifndef HELIB_NORMS_H
129