Statistiques
| Branche: | Révision :

cvp / src / functions_for_cvp.sage @ 9645ea29

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

1
"""@package functions_for_cvp
2
Auxiliary functions used for CVP.
3
"""
4
print "Functions for CVP loading..."
5
#
6
def cvp_babai(redBasis, redBasisGso, vect):
7
    """
8
    Closest plane vector implementation as per Babaï.
9
    @param redBasis   : a lattice basis, preferably a reduced one; 
10
    @param redBasisGSO: the GSO of the previous basis;
11
    @param vector     : a vector, in coordinated in the ambient 
12
                        space of the lattice
13
    @return the closest vector to the input, in coordinates in the 
14
                        ambient space of the lattice.
15
    """
16
    ## A deep copy is not necessary here.
17
    curVect = copy(vect)
18
    print "Vector:", vect
19
    ## From index of last row down to 0.
20
    for vIndex in xrange(len(redBasis.rows())-1, -1, -1):
21
        curRBGSO = redBasisGso.row(vIndex)
22
        curVect = curVect - (round((curVect * curRBGSO)  / (curRBGSO * curRBGSO)) * redBasis.row(vIndex)) 
23
    return vect - curVect
24
#
25

    
26
def cvp_bkz_reduce(intBasis, blockSize):
27
    """
28
    Thin and simplistic wrapper the HKZ function of the FP_LLL module.
29
    """
30
    fplllIntBasis = FP_LLL(intBasis)
31
    fplllIntBasis.BKZ(blockSize)
32
    return fplllIntBasis._sage_()
33
# End cvp_hkz_reduce.
34
#
35

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