Statistiques
| Branche: | Révision :

cvp / src / functions_for_cvp.sage @ 9645ea29

Historique | Voir | Annoter | Télécharger (8,82 ko)

1 9645ea29 Serge Torres
"""@package functions_for_cvp
2 9645ea29 Serge Torres
Auxiliary functions used for CVP.
3 9645ea29 Serge Torres
"""
4 9645ea29 Serge Torres
print "Functions for CVP loading..."
5 9645ea29 Serge Torres
#
6 9645ea29 Serge Torres
def cvp_babai(redBasis, redBasisGso, vect):
7 9645ea29 Serge Torres
    """
8 9645ea29 Serge Torres
    Closest plane vector implementation as per Babaï.
9 9645ea29 Serge Torres
    @param redBasis   : a lattice basis, preferably a reduced one; 
10 9645ea29 Serge Torres
    @param redBasisGSO: the GSO of the previous basis;
11 9645ea29 Serge Torres
    @param vector     : a vector, in coordinated in the ambient 
12 9645ea29 Serge Torres
                        space of the lattice
13 9645ea29 Serge Torres
    @return the closest vector to the input, in coordinates in the 
14 9645ea29 Serge Torres
                        ambient space of the lattice.
15 9645ea29 Serge Torres
    """
16 9645ea29 Serge Torres
    ## A deep copy is not necessary here.
17 9645ea29 Serge Torres
    curVect = copy(vect)
18 9645ea29 Serge Torres
    print "Vector:", vect
19 9645ea29 Serge Torres
    ## From index of last row down to 0.
20 9645ea29 Serge Torres
    for vIndex in xrange(len(redBasis.rows())-1, -1, -1):
21 9645ea29 Serge Torres
        curRBGSO = redBasisGso.row(vIndex)
22 9645ea29 Serge Torres
        curVect = curVect - (round((curVect * curRBGSO)  / (curRBGSO * curRBGSO)) * redBasis.row(vIndex)) 
23 9645ea29 Serge Torres
    return vect - curVect
24 9645ea29 Serge Torres
#
25 9645ea29 Serge Torres
26 9645ea29 Serge Torres
def cvp_bkz_reduce(intBasis, blockSize):
27 9645ea29 Serge Torres
    """
28 9645ea29 Serge Torres
    Thin and simplistic wrapper the HKZ function of the FP_LLL module.
29 9645ea29 Serge Torres
    """
30 9645ea29 Serge Torres
    fplllIntBasis = FP_LLL(intBasis)
31 9645ea29 Serge Torres
    fplllIntBasis.BKZ(blockSize)
32 9645ea29 Serge Torres
    return fplllIntBasis._sage_()
33 9645ea29 Serge Torres
# End cvp_hkz_reduce.
34 9645ea29 Serge Torres
#
35 9645ea29 Serge Torres
36 9645ea29 Serge Torres
def cvp_common_scaling_factor(floatBasis, 
37 9645ea29 Serge Torres
                              funcVect, 
38 9645ea29 Serge Torres
                              precision , 
39 9645ea29 Serge Torres
                              precisionFraction = None):
40 9645ea29 Serge Torres
    """
41 9645ea29 Serge Torres
    Compute the common scaling factor (a power of 2).
42 9645ea29 Serge Torres
    The exponent is made of:
43 ada40619 Serge Torres
       - a fraction of the precision;
44 ada40619 Serge Torres
       - an integer depending on the smallest norm of the vectors of the basis.
45 9645ea29 Serge Torres
    """
46 9645ea29 Serge Torres
    ## Set a default value for the precisionFraction to 1/2.
47 9645ea29 Serge Torres
    if precisionFraction is None:
48 9645ea29 Serge Torres
        precisionFraction = 1/2
49 9645ea29 Serge Torres
    ## Compute the norms of the vectors and get the smallest one.
50 9645ea29 Serge Torres
    #  Start with  "oo" (+Infinty)
51 9645ea29 Serge Torres
    minBasisVectsNorm = oo
52 9645ea29 Serge Torres
    currentNorm = 0
53 9645ea29 Serge Torres
    for vect in floatBasis.rows():
54 9645ea29 Serge Torres
        currentNorm = vect.norm()
55 9645ea29 Serge Torres
        print "Current norm:", currentNorm
56 9645ea29 Serge Torres
        if currentNorm < minBasisVectsNorm:
57 9645ea29 Serge Torres
            minBasisVectsNorm = currentNorm
58 9645ea29 Serge Torres
    currentNorm = funcVect.norm()
59 9645ea29 Serge Torres
    print "Current norm:", currentNorm
60 9645ea29 Serge Torres
    if currentNorm < minBasisVectsNorm:
61 9645ea29 Serge Torres
        minBasisVectsNorm = currentNorm
62 9645ea29 Serge Torres
    ## Check if a push is need because the smallest norm is below 0.    
63 9645ea29 Serge Torres
    powerForMinNorm = floor(log(minBasisVectsNorm)/log2)
64 9645ea29 Serge Torres
    print "Power for min norm :", powerForMinNorm
65 9645ea29 Serge Torres
    print "Power for precision:", ceil(precision*precisionFraction)
66 9645ea29 Serge Torres
    if powerForMinNorm < 0:
67 9645ea29 Serge Torres
        return 2^(ceil(precision*precisionFraction) - powerFromMinNorm)
68 9645ea29 Serge Torres
    else:
69 9645ea29 Serge Torres
        return 2^(ceil(precision*precisionFraction))
70 9645ea29 Serge Torres
# End cvp_common_scaling_factor.
71 9645ea29 Serge Torres
#
72 9645ea29 Serge Torres
def cvp_extra_scaling_factor(floatBasis,
73 9645ea29 Serge Torres
                             funcVect,
74 9645ea29 Serge Torres
                             coeffsPrecList,
75 9645ea29 Serge Torres
                             minExponentsList):
76 9645ea29 Serge Torres
    """
77 9645ea29 Serge Torres
    Compute the extra scaling factor for each element of the basis.
78 9645ea29 Serge Torres
    """
79 9645ea29 Serge Torres
    if floatBasis.nrows() == 0 or \
80 9645ea29 Serge Torres
       floatBasis.ncols() == 0 or \
81 9645ea29 Serge Torres
       len(funcVect) == 0:
82 9645ea29 Serge Torres
        return 0
83 9645ea29 Serge Torres
    ## Compute the norm of the function vector.
84 9645ea29 Serge Torres
    funcVectNorm = funcVect.norm()
85 9645ea29 Serge Torres
    ## Compute the extra scaling factor for each vector of the basis.
86 9645ea29 Serge Torres
    ###  Pass #1 for norms ratios an minExponentsList 
87 9645ea29 Serge Torres
    scalingPowers = []
88 9645ea29 Serge Torres
    normsRatio = 0
89 9645ea29 Serge Torres
    for (row, maxExp) in zip(floatBasis.rows(),minExponentsList):
90 9645ea29 Serge Torres
        normsRatio =  funcVectNorm / row.norm() 
91 9645ea29 Serge Torres
        normsRatioLog2 = normsRatio.log2().floor()
92 9645ea29 Serge Torres
        print "Current norms ratio:", normsRatio, normsRatioLog2
93 9645ea29 Serge Torres
        scalingPower = normsRatioLog2 + maxExp
94 9645ea29 Serge Torres
        print "Current scaling power:", scalingPower
95 9645ea29 Serge Torres
        scalingPowers.append(scalingPower)
96 9645ea29 Serge Torres
    ### Pass #2 for coefficients precision.
97 9645ea29 Serge Torres
    minScalingPower = oo
98 9645ea29 Serge Torres
    for index in xrange(0,len(scalingPowers)):
99 9645ea29 Serge Torres
        scalingPowers[index] -= coeffsPrecList[index]
100 9645ea29 Serge Torres
        if scalingPowers[index] < minScalingPower:
101 9645ea29 Serge Torres
            minScalingPower = scalingPowers[index]
102 9645ea29 Serge Torres
            print "Current scaling power:", scalingPowers[index]
103 9645ea29 Serge Torres
    if minScalingPower < 0:
104 9645ea29 Serge Torres
        scalingFactor = 2^(-minScalingPower)
105 9645ea29 Serge Torres
    else:
106 9645ea29 Serge Torres
        scalingFactor = 1
107 9645ea29 Serge Torres
    return (scalingFactor, scalingPowers)
108 9645ea29 Serge Torres
# End cvp_extra_scaling_factor.
109 9645ea29 Serge Torres
#
110 9645ea29 Serge Torres
def cvp_float_basis(monomialsList, pointsList, realField):
111 9645ea29 Serge Torres
    """
112 9645ea29 Serge Torres
    For a given monomials list and points list, compute the floating-point
113 9645ea29 Serge Torres
    basis matrix.
114 9645ea29 Serge Torres
    """
115 9645ea29 Serge Torres
    numRows    = len(monomialsList)
116 9645ea29 Serge Torres
    numCols    = len(pointsList)
117 9645ea29 Serge Torres
    if numRows == 0 or numCols == 0:
118 9645ea29 Serge Torres
        return matrix(realField, 0, 0)
119 9645ea29 Serge Torres
    #
120 9645ea29 Serge Torres
    floatBasis = matrix(realField, numRows, numCols)
121 9645ea29 Serge Torres
    for rIndex in xrange(0, numRows):
122 9645ea29 Serge Torres
        for cIndex in xrange(0, numCols):
123 9645ea29 Serge Torres
            floatBasis[rIndex,cIndex] = \
124 9645ea29 Serge Torres
                monomialsList[rIndex](realField(pointsList[cIndex]))
125 9645ea29 Serge Torres
    return floatBasis
126 9645ea29 Serge Torres
# End cvp_float_basis
127 9645ea29 Serge Torres
#
128 9645ea29 Serge Torres
def cvp_float_vector_for_approx(func, 
129 9645ea29 Serge Torres
                                basisPointsList,
130 9645ea29 Serge Torres
                                realField):
131 9645ea29 Serge Torres
    """
132 9645ea29 Serge Torres
    Compute a floating-point vector for the function and the points list.
133 9645ea29 Serge Torres
    """
134 9645ea29 Serge Torres
    #
135 9645ea29 Serge Torres
    ## Some local variables.
136 9645ea29 Serge Torres
    basisPointsNum = len(basisPointsList)
137 9645ea29 Serge Torres
    #
138 9645ea29 Serge Torres
    ##
139 9645ea29 Serge Torres
    vVect = vector(realField, basisPointsNum)
140 9645ea29 Serge Torres
    for vIndex in xrange(0,basisPointsNum):
141 9645ea29 Serge Torres
        vVect[vIndex] = \
142 9645ea29 Serge Torres
            func(basisPointsList[vIndex])
143 9645ea29 Serge Torres
    return vVect
144 9645ea29 Serge Torres
# End cvp_float_vector_for_approx.
145 9645ea29 Serge Torres
#
146 9645ea29 Serge Torres
def cvp_hkz_reduce(intBasis):
147 9645ea29 Serge Torres
    """
148 9645ea29 Serge Torres
    Thin and simplistic wrapper the HKZ function of the FP_LLL module.
149 9645ea29 Serge Torres
    """
150 9645ea29 Serge Torres
    fplllIntBasis = FP_LLL(intBasis)
151 9645ea29 Serge Torres
    fplllIntBasis.HKZ()
152 9645ea29 Serge Torres
    return fplllIntBasis._sage_()
153 9645ea29 Serge Torres
# End cvp_hkz_reduce.
154 9645ea29 Serge Torres
#
155 9645ea29 Serge Torres
def cvp_int_basis(floatBasis, commonScalingFactor):
156 9645ea29 Serge Torres
    """
157 9645ea29 Serge Torres
    From the float basis and the common scaling factor, compute the
158 9645ea29 Serge Torres
    integral basis.
159 9645ea29 Serge Torres
    """
160 9645ea29 Serge Torres
    intBasis = matrix(ZZ, floatBasis.nrows(), floatBasis.ncols())
161 9645ea29 Serge Torres
    for rIndex in xrange(0, floatBasis.nrows()):
162 9645ea29 Serge Torres
        for cIndex in xrange(0, floatBasis.ncols()):
163 9645ea29 Serge Torres
            intBasis[rIndex, cIndex] = \
164 9645ea29 Serge Torres
            floatBasis[rIndex, cIndex] * commonScalingFactor
165 9645ea29 Serge Torres
    return intBasis
166 9645ea29 Serge Torres
# End cvp_int_basis.
167 9645ea29 Serge Torres
#
168 9645ea29 Serge Torres
def cvp_int_vector_for_approx(floatVect, commonScalingFactor, extraScalingFactor):
169 9645ea29 Serge Torres
    totalScalingFactor = commonScalingFactor * extraScalingFactor
170 9645ea29 Serge Torres
    intVect = vector(ZZ, len(floatVect))
171 9645ea29 Serge Torres
    for index in xrange(0, len(floatVect)):
172 9645ea29 Serge Torres
        intVect[index] = (floatVect[index] * totalScalingFactor).round()
173 9645ea29 Serge Torres
    return intVect
174 9645ea29 Serge Torres
# End cvp_int_vector_for_approx.
175 9645ea29 Serge Torres
#
176 9645ea29 Serge Torres
def cvp_lll_reduce(intBasis):
177 9645ea29 Serge Torres
    """
178 9645ea29 Serge Torres
    Thin and simplistic wrapper around the LLL function
179 9645ea29 Serge Torres
    """
180 9645ea29 Serge Torres
    return intBasis.LLL()
181 9645ea29 Serge Torres
# End cvp_lll_reduce.
182 9645ea29 Serge Torres
#
183 9645ea29 Serge Torres
def cvp_monomials_list(exponentsList, varName = None):
184 9645ea29 Serge Torres
    """
185 9645ea29 Serge Torres
    Create a list of monomials corresponding to the given exponentsList.
186 9645ea29 Serge Torres
    Monomials are defined as functions.
187 9645ea29 Serge Torres
    """
188 9645ea29 Serge Torres
    monomialsList = []
189 9645ea29 Serge Torres
    for exponent in exponentsList:
190 9645ea29 Serge Torres
        if varName is None:
191 9645ea29 Serge Torres
            monomialsList.append((x^exponent).function(x))
192 9645ea29 Serge Torres
        else:
193 9645ea29 Serge Torres
            monomialsList.append((varName^exponent).function(varName))
194 9645ea29 Serge Torres
    return monomialsList
195 9645ea29 Serge Torres
# End cvp_monomials_list.
196 9645ea29 Serge Torres
#
197 9645ea29 Serge Torres
def cvp_vector_in_basis(vect, basis):
198 9645ea29 Serge Torres
    """
199 9645ea29 Serge Torres
    Compute the coordinates of "vect" in "basis" by
200 9645ea29 Serge Torres
    solving a linear system.
201 9645ea29 Serge Torres
    @param vect : the vector we want to compute the coordinates of
202 9645ea29 Serge Torres
                  in coordinates of the ambient space;
203 9645ea29 Serge Torres
    @param basis: the basis we want to compute the coordinates in
204 9645ea29 Serge Torres
                  as a matrix relative to the ambient space.
205 9645ea29 Serge Torres
    """
206 9645ea29 Serge Torres
    ## Create the variables for the linear equations.
207 9645ea29 Serge Torres
    varDeclString = ""
208 9645ea29 Serge Torres
    basisIterationsRange = xrange(0, basis.nrows())
209 9645ea29 Serge Torres
    ### Building variables declaration string.
210 9645ea29 Serge Torres
    for index in basisIterationsRange:
211 9645ea29 Serge Torres
        varName = "a" + str(index)
212 9645ea29 Serge Torres
        if varDeclString == "":
213 9645ea29 Serge Torres
            varDeclString += varName
214 9645ea29 Serge Torres
        else:
215 9645ea29 Serge Torres
            varDeclString += "," + varName
216 9645ea29 Serge Torres
    ### Variables declaration
217 9645ea29 Serge Torres
    varsList = var(varDeclString)
218 9645ea29 Serge Torres
    sage_eval("var('" + varDeclString + "')")
219 9645ea29 Serge Torres
    ## Create the equations
220 9645ea29 Serge Torres
    equationString = ""
221 9645ea29 Serge Torres
    equationsList = []
222 9645ea29 Serge Torres
    for vIndex in xrange(0, len(vect)):
223 9645ea29 Serge Torres
        equationString = ""
224 9645ea29 Serge Torres
        for bIndex in basisIterationsRange:
225 9645ea29 Serge Torres
            if equationString != "":
226 9645ea29 Serge Torres
                equationString += "+"
227 9645ea29 Serge Torres
            equationString += str(varsList[bIndex]) + "*" + str(basis[bIndex,vIndex])
228 9645ea29 Serge Torres
        equationString += " == " + str(vect[vIndex])
229 9645ea29 Serge Torres
        equationsList.append(sage_eval(equationString))
230 9645ea29 Serge Torres
    ## Solve the equations system. The solution dictionnary is needed
231 9645ea29 Serge Torres
    #  to recover the values of the solutions.
232 9645ea29 Serge Torres
    solutions = solve(equationsList,varsList, solution_dict=True)
233 9645ea29 Serge Torres
    #print "Solutions:", s
234 9645ea29 Serge Torres
    ## Recover solutions in rational components vector.
235 9645ea29 Serge Torres
    vectInBasis = vector(QQ, basis.nrows())
236 9645ea29 Serge Torres
    ### There can be several solution, in the general case.
237 9645ea29 Serge Torres
    #   Here, there is only one. For each solution, each 
238 9645ea29 Serge Torres
    #   variable has to be searched for.
239 9645ea29 Serge Torres
    for sol in solutions:
240 9645ea29 Serge Torres
        for bIndex in basisIterationsRange:
241 9645ea29 Serge Torres
            vectInBasis[bIndex] = sol[varsList[bIndex]]
242 9645ea29 Serge Torres
    return vectInBasis
243 9645ea29 Serge Torres
# End cpv_vector_in_basis.
244 9645ea29 Serge Torres
#
245 9645ea29 Serge Torres
print "... functions for CVP loaded."