Révision 172 pobysoPythonSage/src/sageSLZ/sageSLZ.sage
sageSLZ.sage (revision 172) | ||
---|---|---|
95 | 95 |
2^m <= number < 2^(m+1). If number == 0 return None. |
96 | 96 |
""" |
97 | 97 |
# Checking the parameter. |
98 |
# The exception construction is used to detect if numbre is a RealNumber
|
|
98 |
# The exception construction is used to detect if number is a RealNumber
|
|
99 | 99 |
# since not all numbers have |
100 | 100 |
# the mro() method. sage.rings.real_mpfr.RealNumber do. |
101 | 101 |
try: |
102 | 102 |
classTree = [number.__class__] + number.mro() |
103 |
# If the number is not a RealNumber (of offspring thereof) try
|
|
103 |
# If the number is not a RealNumber (or offspring thereof) try
|
|
104 | 104 |
# to transform it. |
105 | 105 |
if not sage.rings.real_mpfr.RealNumber in classTree: |
106 | 106 |
numberAsRR = RR(number) |
... | ... | |
624 | 624 |
scaled back by dividing by the "right" powers of the variables bounds. |
625 | 625 |
|
626 | 626 |
The elements in knownMonomials must be of the "right" polynomial type. |
627 |
They set the polynomial type of the output polynomials list. |
|
627 |
They set the polynomial type of the output polynomials in list.
|
|
628 | 628 |
@param reducedMatrix: the reduced matrix as output from LLL; |
629 | 629 |
@param kwnonMonomials: the ordered list of the monomials used to |
630 | 630 |
build the polynomials; |
... | ... | |
1055 | 1055 |
return((polynomialSa, polynomialChangedVarSa, intervalSa, centerSa, errorSa)) |
1056 | 1056 |
# End slz_interval_and_polynomial_to_sage |
1057 | 1057 |
|
1058 |
def slz_is_htrn(argument, function, targetAccuracy, targetRF = None, |
|
1059 |
targetPlusOnePrecRF = None, quasiExactRF = None): |
|
1060 |
""" |
|
1061 |
Check if an element (argument) of the domain of function (function) |
|
1062 |
yields a HTRN case (rounding to next) for the target precision |
|
1063 |
(as impersonated by targetRF) for a given accuracy (targetAccuraty). |
|
1064 |
""" |
|
1065 |
## Arguments filtering. TODO: filter the first argument for consistence. |
|
1066 |
## If no target accuracy is given, assume it is that of the argument. |
|
1067 |
if targetRF is None: |
|
1068 |
targetRF = argument.parent() |
|
1069 |
## Ditto for the real field holding the midpoints. |
|
1070 |
if targetPlusOnePrecRF is None: |
|
1071 |
targetPlusOnePrecRF = RealField(targetRF.prec()+1) |
|
1072 |
## Create a high accuracy RealField |
|
1073 |
if quasiExactRF is None: |
|
1074 |
quasiExactRF = RealField(1536) |
|
1075 |
|
|
1076 |
exactArgument = quasiExactRF(argument) |
|
1077 |
quasiExactValue = function(exactArgument) |
|
1078 |
roundedValue = targetRF(quasiExactValue) |
|
1079 |
roundedValuePrecPlusOne = targetPlusOnePrecRF(roundedValue) |
|
1080 |
# Upper midpoint. |
|
1081 |
roundedValuePrecPlusOneNext = roundedValuePrecPlusOne.nextabove() |
|
1082 |
# Lower midpoint. |
|
1083 |
roundedValuePrecPlusOnePrev = roundedValuePrecPlusOne.nextbelow() |
|
1084 |
binade = slz_compute_binade(roundedValue) |
|
1085 |
binadeCorrectedTargetAccuracy = targetAccuracy * 2^binade |
|
1086 |
#print "Argument:", argument |
|
1087 |
#print "f(x):", roundedValue, binade, floor(binade), ceil(binade) |
|
1088 |
#print "binadeCorrectedTargetAccuracy:", \ |
|
1089 |
# binadeCorrectedTargetAccuracy.n(prec=100) |
|
1090 |
#print "binadeCorrectedTargetAccuracy:", \ |
|
1091 |
# binadeCorrectedTargetAccuracy.n(prec=100).str(base=2) |
|
1092 |
#print "Upper midpoint:", \ |
|
1093 |
# roundedValuePrecPlusOneNext.n(prec=targetPlusOnePrecRF.prec()).str(base=2) |
|
1094 |
#print "Rounded value :", \ |
|
1095 |
# roundedValuePrecPlusOne.n(prec=targetPlusOnePrecRF.prec()).str(base=2), \ |
|
1096 |
# roundedValuePrecPlusOne.ulp().n(prec=2).str(base=2) |
|
1097 |
#print "QuasiEx value :", quasiExactValue.n(prec=250).str(base=2) |
|
1098 |
#print "Lower midpoint:", \ |
|
1099 |
# roundedValuePrecPlusOnePrev.n(prec=targetPlusOnePrecRF.prec()).str(base=2) |
|
1100 |
## Begining of the general case : check with the midpoint with |
|
1101 |
# greatest absolute value. |
|
1102 |
if quasiExactValue > 0: |
|
1103 |
if abs(quasiExactRF(roundedValuePrecPlusOneNext) - quasiExactValue) <\ |
|
1104 |
binadeCorrectedTargetAccuracy: |
|
1105 |
#print "Too close to the upper midpoint: ", \ |
|
1106 |
abs(quasiExactRF(roundedValuePrecPlusOneNext) - quasiExactValue).n(prec=100) |
|
1107 |
#print argument.n().str(base=16, \ |
|
1108 |
# no_sci=False) |
|
1109 |
#print "Lower midpoint:", \ |
|
1110 |
# roundedValuePrecPlusOnePrev.n(prec=targetPlusOnePrecRF.prec()).str(base=2) |
|
1111 |
#print "Value :", \ |
|
1112 |
# quasiExactValue.n(prec=200).str(base=2) |
|
1113 |
#print "Upper midpoint:", \ |
|
1114 |
# roundedValuePrecPlusOneNext.n(prec=targetPlusOnePrecRF.prec()).str(base=2) |
|
1115 |
|
|
1116 |
return True |
|
1117 |
else: |
|
1118 |
if abs(quasiExactRF(roundedValuePrecPlusOnePrev) - quasiExactValue) < \ |
|
1119 |
binadeCorrectedTargetAccuracy: |
|
1120 |
#print "Too close to the upper midpoint: ", \ |
|
1121 |
# abs(quasiExactRF(roundedValuePrecPlusOneNext) - quasiExactValue).n(prec=100) |
|
1122 |
#print argument.n().str(base=16, \ |
|
1123 |
# no_sci=False) |
|
1124 |
#print "Lower midpoint:", \ |
|
1125 |
# roundedValuePrecPlusOnePrev.n(prec=targetPlusOnePrecRF.prec()).str(base=2) |
|
1126 |
#print "Value :", \ |
|
1127 |
# quasiExactValue.n(prec=200).str(base=2) |
|
1128 |
#print "Upper midpoint:", \ |
|
1129 |
# roundedValuePrecPlusOneNext.n(prec=targetPlusOnePrecRF.prec()).str(base=2) |
|
1130 |
|
|
1131 |
return True |
|
1132 |
#2345678901234567890123456789012345678901234567890123456789012345678901234567890 |
|
1133 |
## For the midpoint of smaller absolute value, |
|
1134 |
# split cases with the powers of 2. |
|
1135 |
if sno_abs_is_power_of_two(roundedValue): |
|
1136 |
if quasiExactValue > 0: |
|
1137 |
if abs(quasiExactRF(roundedValuePrecPlusOnePrev) - quasiExactValue) <\ |
|
1138 |
binadeCorrectedTargetAccuracy / 2: |
|
1139 |
#print "Lower midpoint:", \ |
|
1140 |
# roundedValuePrecPlusOnePrev.n(prec=targetPlusOnePrecRF.prec()).str(base=2) |
|
1141 |
#print "Value :", \ |
|
1142 |
# quasiExactValue.n(prec=200).str(base=2) |
|
1143 |
#print "Upper midpoint:", \ |
|
1144 |
# roundedValuePrecPlusOneNext.n(prec=targetPlusOnePrecRF.prec()).str(base=2) |
|
1145 |
|
|
1146 |
return True |
|
1147 |
else: |
|
1148 |
if abs(quasiExactRF(roundedValuePrecPlusOneNext) - quasiExactValue) < \ |
|
1149 |
binadeCorrectedTargetAccuracy / 2: |
|
1150 |
#print "Lower midpoint:", \ |
|
1151 |
# roundedValuePrecPlusOnePrev.n(prec=targetPlusOnePrecRF.prec()).str(base=2) |
|
1152 |
#print "Value :", |
|
1153 |
# quasiExactValue.n(prec=200).str(base=2) |
|
1154 |
#print "Upper midpoint:", |
|
1155 |
# roundedValuePrecPlusOneNext.n(prec=targetPlusOnePrecRF.prec()).str(base=2) |
|
1156 |
|
|
1157 |
return True |
|
1158 |
#2345678901234567890123456789012345678901234567890123456789012345678901234567890 |
|
1159 |
else: ## Not a power of 2, regular comparison with the midpoint of |
|
1160 |
# smaller absolute value. |
|
1161 |
if quasiExactValue > 0: |
|
1162 |
if abs(quasiExactRF(roundedValuePrecPlusOnePrev) - quasiExactValue) < \ |
|
1163 |
binadeCorrectedTargetAccuracy: |
|
1164 |
#print "Lower midpoint:", \ |
|
1165 |
# roundedValuePrecPlusOnePrev.n(prec=targetPlusOnePrecRF.prec()).str(base=2) |
|
1166 |
#print "Value :", \ |
|
1167 |
# quasiExactValue.n(prec=200).str(base=2) |
|
1168 |
#print "Upper midpoint:", \ |
|
1169 |
# roundedValuePrecPlusOneNext.n(prec=targetPlusOnePrecRF.prec()).str(base=2) |
|
1170 |
|
|
1171 |
return True |
|
1172 |
else: # quasiExactValue <= 0 |
|
1173 |
if abs(quasiExactRF(roundedValuePrecPlusOneNext) - quasiExactValue) < \ |
|
1174 |
binadeCorrectedTargetAccuracy: |
|
1175 |
#print "Lower midpoint:", \ |
|
1176 |
# roundedValuePrecPlusOnePrev.n(prec=targetPlusOnePrecRF.prec()).str(base=2) |
|
1177 |
#print "Value :", \ |
|
1178 |
# quasiExactValue.n(prec=200).str(base=2) |
|
1179 |
#print "Upper midpoint:", \ |
|
1180 |
# roundedValuePrecPlusOneNext.n(prec=targetPlusOnePrecRF.prec()).str(base=2) |
|
1181 |
|
|
1182 |
return True |
|
1183 |
#print "distance to the upper midpoint:", \ |
|
1184 |
# abs(quasiExactRF(roundedValuePrecPlusOneNext) - quasiExactValue).n(prec=100).str(base=2) |
|
1185 |
#print "distance to the lower midpoint:", \ |
|
1186 |
# abs(quasiExactRF(roundedValuePrecPlusOnePrev) - quasiExactValue).n(prec=100).str(base=2) |
|
1187 |
return False |
|
1188 |
# End slz_is_htrn |
|
1189 |
|
|
1058 | 1190 |
def slz_rat_poly_of_int_to_poly_for_coppersmith(ratPolyOfInt, |
1059 | 1191 |
precision, |
1060 | 1192 |
targetHardnessToRound, |
Formats disponibles : Unified diff