Révision 62861417 src/functions_for_cvp.sage

b/src/functions_for_cvp.sage
15 15
    """
16 16
    ## A deep copy is not necessary here.
17 17
    curVect = copy(vect)
18
    print "Vector:", vect
18
    print "cvp_babai - Vector:", vect
19 19
    ## From index of last row down to 0.
20 20
    for vIndex in xrange(len(redBasis.rows())-1, -1, -1):
21 21
        curRBGSO = redBasisGso.row(vIndex)
22 22
        curVect = curVect - (round((curVect * curRBGSO)  / (curRBGSO * curRBGSO)) * redBasis.row(vIndex)) 
23 23
    return vect - curVect
24
# End cvp_babai
24 25
#
25

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

  
36
def cvp_common_scaling_factor(floatBasis, 
37
                              funcVect, 
38
                              precision , 
39
                              precisionFraction = None):
35
def cvp_common_scaling_exp(precision, 
36
                           precisionFraction = None):
40 37
    """
41 38
    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.
39
    The exponent is a fraction of the precision;
40
    A extra factor is computed for the vector,
41
    exra factors are computed for the basis vectors, all in the corresponding
42
    functions.
45 43
    """
46 44
    ## Set a default value for the precisionFraction to 1/2.
47 45
    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)
46
        precisionFraction = 3/4
47
    """
51 48
    minBasisVectsNorm = oo
52 49
    currentNorm = 0
53 50
    for vect in floatBasis.rows():
......
66 63
    if powerForMinNorm < 0:
67 64
        return 2^(ceil(precision*precisionFraction) - powerFromMinNorm)
68 65
    else:
69
        return 2^(ceil(precision*precisionFraction))
66
    """
67
    return ceil(precision * precisionFraction)
70 68
# End cvp_common_scaling_factor.
71 69
#
72
def cvp_extra_scaling_factor(floatBasis,
73
                             funcVect,
74
                             coeffsPrecList,
75
                             minExponentsList):
70
def cvp_extra_basis_scaling_exps(precsList, minExponentsList):
71
    extraScalingExpsList = []
72
    for minExp, prec in zip(minExponentsList, precsList):
73
        if minExp - prec < 0:
74
            extraScalingExpsList.append(minExp - prec)
75
        else:
76
            extraScalingExpsList.append(0)
77
    return extraScalingExpsList
78
# End cvp_extra_basis_scaling_exps.
79
#
80
def cvp_extra_function_scaling_exp(floatBasis,
81
                                   floatFuncVect,
82
                                   maxExponentsList):
76 83
    """
77
    Compute the extra scaling factor for each element of the basis.
84
    Compute the extra scaling exponent for the function vector in ordre to 
85
    guarantee that the maximum exponent can be reached for each element of the
86
    basis.
78 87
    """
88
    ## Check arguments
79 89
    if floatBasis.nrows() == 0 or \
80 90
       floatBasis.ncols() == 0 or \
81
       len(funcVect) == 0:
82
        return 0
83
    ## Compute the norm of the function vector.
84
    funcVectNorm = funcVect.norm()
91
       len(floatFuncVect)      == 0:
92
        return 1
93
    if len(maxExponentsList) != floatBasis.nrows():
94
        return None
95
    ## Compute the log of the norm of the function vector.
96
    funcVectNormLog  = log(floatFuncVect.norm())
85 97
    ## 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.
98
    #  for norms ratios an maxExponentsList. 
99
    extraScalingExp = 0
100
    for (row, maxExp) in zip(floatBasis.rows(),maxExponentsList):
101
        rowNormLog     = log(row.norm())
102
        normsRatioLog2 = floor((funcVectNormLog - rowNormLog) / log2) 
103
        #print "Current norms ratio log2:", normsRatioLog2
104
        scalingExpCandidate = normsRatioLog2 - maxExp 
105
        #print "Current scaling exponent candidate:", scalingExpCandidate
106
        if scalingExpCandidate < 0:
107
            if -scalingExpCandidate > extraScalingExp:
108
                extraScalingExp = -scalingExpCandidate
109
    return extraScalingExp
110
# End cvp_extra_function_scaling_exp.
109 111
#
110 112
def cvp_float_basis(monomialsList, pointsList, realField):
111 113
    """
......
152 154
    return fplllIntBasis._sage_()
153 155
# End cvp_hkz_reduce.
154 156
#
155
def cvp_int_basis(floatBasis, commonScalingFactor):
157
def cvp_int_basis(floatBasis, 
158
                  commonScalingExp, 
159
                  extraScalingExpsList):
156 160
    """
157
    From the float basis and the common scaling factor, compute the
158
    integral basis.
161
    From the float basis, the common scaling factor and the extra exponents 
162
    compute the integral basis.
159 163
    """
164
    ## Checking arguments.
165
    if floatBasis.nrows() != len(extraScalingExpsList):
166
        return None
160 167
    intBasis = matrix(ZZ, floatBasis.nrows(), floatBasis.ncols())
161 168
    for rIndex in xrange(0, floatBasis.nrows()):
162 169
        for cIndex in xrange(0, floatBasis.ncols()):
163 170
            intBasis[rIndex, cIndex] = \
164
            floatBasis[rIndex, cIndex] * commonScalingFactor
171
            floatBasis[rIndex, cIndex] * \
172
            2^(commonScalingExp + extraScalingExpsList[rIndex])
165 173
    return intBasis
166 174
# End cvp_int_basis.
167 175
#
168
def cvp_int_vector_for_approx(floatVect, commonScalingFactor, extraScalingFactor):
169
    totalScalingFactor = commonScalingFactor * extraScalingFactor
176
def cvp_int_vector_for_approx(floatVect, commonScalingExp, extraScalingExp):
177
    totalScalingFactor = 2^(commonScalingExp + extraScalingExp)
170 178
    intVect = vector(ZZ, len(floatVect))
171 179
    for index in xrange(0, len(floatVect)):
172 180
        intVect[index] = (floatVect[index] * totalScalingFactor).round()
......
194 202
    return monomialsList
195 203
# End cvp_monomials_list.
196 204
#
205
def cvp_polynomial_coeffs_from_vect(cvpVectInBasis,
206
                                   coeffsPrecList, 
207
                                   minCoeffsExpList,
208
                                   extraFuncScalingExp):
209
    numElements = len(cvpVectInBasis)
210
    ## Arguments check.
211
    if numElements != len(minCoeffsExpList) or \
212
       numElements != len(coeffsPrecList):
213
        return None
214
    polynomialCoeffsList = []
215
    for index in xrange(0, numElements):
216
        currentCoeff = cvp_round_to_bits(cvpVectInBasis[index],
217
                                         coeffsPrecList[index])
218
        print "cvp_polynomial_coeffs - current coefficient rounded:", currentCoeff
219
        currentCoeff *= 2^(minCoeffsExpList[index])
220
        print "cvp_polynomial_coeffs - current coefficient scaled :", currentCoeff
221
        currentCoeff *= 2^(-coeffsPrecList[index])
222
        print "cvp_polynomial_coeffs - current coefficient prec corrected :", currentCoeff
223
        currentCoeff *= 2^(-extraFuncScalingExp)
224
        print "cvp_polynomial_coeffs - current coefficient extra func scaled :", currentCoeff
225
        polynomialCoeffsList.append(currentCoeff)
226
    return polynomialCoeffsList
227
# En polynomial_coeffs_from_vect.
228
#
229
def cvp_round_to_bits(num, numBits):
230
    """
231
    Round "num" to "numBits" bits.
232
    @param num    : the number to round;
233
    @param numBits: the number of bits to round to.
234
    """
235
    if num == 0:
236
        return num
237
    log2ofNum  = 0
238
    numRounded = 0
239
    ## Avoid conversion to floating-point if not necessary.
240
    try:
241
        log2OfNum = num.abs().log2()
242
    except:
243
        log2OfNum = RR(num).abs().log2()
244
    ## Works equally well for num >= 1 and num < 1.
245
    log2OfNum = ceil(log2OfNum)
246
    # print "cvp_round_to_bits - Log2OfNum:", log2OfNum
247
    divMult = log2OfNum - numBits
248
    #print "cvp_round_to_bits - DivMult:", divMult
249
    if divMult != 0:
250
        numRounded = round(num/2^divMult) * 2^divMult
251
    else:
252
        numRounded = num
253
    return numRounded
254
# End cvp_round_to_bits
255
#
197 256
def cvp_vector_in_basis(vect, basis):
198 257
    """
199 258
    Compute the coordinates of "vect" in "basis" by

Formats disponibles : Unified diff