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