Index: sageSLZ.sage
===================================================================
--- sageSLZ.sage	(revision 79)
+++ sageSLZ.sage	(revision 80)
@@ -58,7 +58,6 @@
     # End slz_compute_polynomial_and_interval
 
 def slz_compute_scaled_function(functionSa, \
-                                      variableNameSa, \
                                       lowerBoundSa, \
                                       upperBoundSa, \
                                       floatingPointPrecSa):
@@ -72,18 +71,21 @@
     [3]: the scaled image lower bound
     [4]: the scaled image upper bound
     """
-    x = var(variableNameSa)
+    x = functionSa.variables()[0]
+    # Reassert f as a function (an not a mere expression).
+    
     # Scalling the domain -> [1,2[.
     boundsIntervalRifSa = RealIntervalField(floatingPointPrecSa)
     domainBoundsIntervalSa = boundsIntervalRifSa(lowerBoundSa, upperBoundSa)
     (domainScalingExpressionSa, invDomainScalingExpressionSa) = \
-        slz_interval_scaling_expression(domainBoundsIntervalSa, variableNameSa)
+        slz_interval_scaling_expression(domainBoundsIntervalSa, x)
     print "domainScalingExpression for argument :", domainScalingExpressionSa
     print "f: ", f
     ff = f.subs({x : domainScalingExpressionSa})
     #ff = f.subs_expr(x==domainScalingExpressionSa)
-    scaledLowerBoundSa = invDomainScalingExpressionSa(lowerBoundSa).n()
-    scaledUpperBoundSa = invDomainScalingExpressionSa(upperBoundSa).n()
+    domainScalingFunction(x) = invDomainScalingExpressionSa
+    scaledLowerBoundSa = domainScalingFunction(lowerBoundSa).n()
+    scaledUpperBoundSa = domainScalingFunction(upperBoundSa).n()
     print 'ff:', ff, "- Domain:", scaledLowerBoundSa, scaledUpperBoundSa
     #
     # Scalling the image -> [1,2[.
@@ -96,7 +98,7 @@
     print 'ff:', ff, '- Image:', flbSa, fubSa, imageBinadeBottomSa
     imageBoundsIntervalSa = boundsIntervalRifSa(flbSa, fubSa)
     (imageScalingExpressionSa, invImageScalingExpressionSa) = \
-        slz_interval_scaling_expression(imageBoundsIntervalSa, variableNameSa)
+        slz_interval_scaling_expression(imageBoundsIntervalSa, x)
     iis = invImageScalingExpressionSa.function(x)
     fff = iis.subs({x:ff})
     print "fff:", fff,
@@ -110,7 +112,7 @@
     return(polynomialRing(polyOfFloat))
 # End slz_float_poly_of_float_to_rat_poly_of_rat
      
-def slz_get_intervals_and_polynomials(functionSa, variableNameSa, degreeSa, 
+def slz_get_intervals_and_polynomials(functionSa, degreeSa, 
                                       lowerBoundSa, 
                                       upperBoundSa, floatingPointPrecSa, 
                                       internalSollyaPrecSa, approxPrecSa):
@@ -133,36 +135,14 @@
     - the center, x0, of the interval;
     - the corresponding approximation error.
     """
-    x = var(variableNameSa)
-    # Scalling the domain -> [1,2[.
-    boundsIntervalRifSa = RealIntervalField(floatingPointPrecSa)
-    domainBoundsIntervalSa = boundsIntervalRifSa(lowerBoundSa, upperBoundSa)
-    (domainScalingExpressionSa, invDomainScalingExpressionSa) = \
-        slz_interval_scaling_expression(domainBoundsIntervalSa, variableNameSa)
-    print "domainScalingExpression for argument :", domainScalingExpressionSa
-    print "f: ", f
-    ff = f.subs({x : domainScalingExpressionSa})
-    #ff = f.subs_expr(x==domainScalingExpressionSa)
-    scaledLowerBoundSa = invDomainScalingExpressionSa(lowerBoundSa).n()
-    scaledUpperBoundSa = invDomainScalingExpressionSa(upperBoundSa).n()
-    print 'ff:', ff, "- Domain:", scaledLowerBoundSa, scaledUpperBoundSa
+    x = functionSa.variables()[0] # Actual variable name can be anything.
+    (fff, scaledLowerBoundSa, scaledUpperBoundSa, \
+            scaledLowerBoundImageSa, scaledUpperBoundImageSa) = \
+                slz_compute_scaled_function(functionSa, \
+                                            lowerBoundSa, \
+                                            upperBoundSa, \
+                                            floatingPointPrecSa)
     #
-    # Scalling the image -> [1,2[.
-    flbSa = f(lowerBoundSa).n()
-    fubSa = f(upperBoundSa).n()
-    if flbSa <= fubSa: # Increasing
-        imageBinadeBottomSa = floor(flbSa.log2())
-    else: # Decreasing
-        imageBinadeBottomSa = floor(fubSa.log2())
-    print 'ff:', ff, '- Image:', flbSa, fubSa, imageBinadeBottomSa
-    imageBoundsIntervalSa = boundsIntervalRifSa(flbSa, fubSa)
-    (imageScalingExpressionSa, invImageScalingExpressionSa) = \
-        slz_interval_scaling_expression(imageBoundsIntervalSa, variableNameSa)
-    iis = invImageScalingExpressionSa.function(x)
-    fff = iis.subs({x:ff})
-    print "fff:", fff,
-    print " - Image:", fff(scaledLowerBoundSa), fff(scaledUpperBoundSa)
-    #
     resultArray = []
     #
     print "Approximation precision: ", RR(approxPrecSa)
@@ -208,7 +188,7 @@
     return(resultArray)
     # End slz_get_intervals_and_polynomials
 
-def slz_interval_scaling_expression(boundsInterval, varName):
+def slz_interval_scaling_expression(boundsInterval, expVar):
     """
     Compute the scaling expression to map an interval that span only
     a binade to [1, 2) and the inverse expression as well.
@@ -219,27 +199,27 @@
         if boundsInterval.endpoints()[0] >= 0:
             scalingCoeff = 2^floor(boundsInterval.endpoints()[0].log2())
             invScalingCoeff = 1/scalingCoeff
-            return((scalingCoeff * eval(varName), 
-                    invScalingCoeff * eval(varName)))
+            return((scalingCoeff * expVar, 
+                    invScalingCoeff * expVar))
         else:
             scalingCoeff = \
                 2^(floor((-boundsInterval.endpoints()[0]).log2()) - 1)
             scalingOffset = -3 * scalingCoeff
-            return((scalingCoeff * eval(varName) + scalingOffset,
-                    1/scalingCoeff * eval(varName) + 3))
+            return((scalingCoeff * expVar + scalingOffset,
+                    1/scalingCoeff * expVar + 3))
     else: 
         if boundsInterval.endpoints()[0] >= 0:
             scalingCoeff = 2^floor(boundsInterval.endpoints()[0].log2())
             scalingOffset = 0
-            return((scalingCoeff * eval(varName), 
-                    1/scalingCoeff * eval(varName)))
+            return((scalingCoeff * expVar, 
+                    1/scalingCoeff * expVar))
         else:
             scalingCoeff = \
                 2^(floor((-boundsInterval.endpoints()[1]).log2()))
             scalingOffset =  -3 * scalingCoeff
             #scalingOffset = 0
-            return((scalingCoeff * eval(varName) + scalingOffset,
-                    1/scalingCoeff * eval(varName) + 3))
+            return((scalingCoeff * expVar + scalingOffset,
+                    1/scalingCoeff * expVar + 3))
 
    
 def slz_polynomial_and_interval_to_sage(polyRangeCenterErrorSo):
@@ -269,9 +249,50 @@
     return((polynomialSa, polynomialChangedVarSa, intervalSa, centerSa, errorSa))
     # End slz_polynomial_and_interval_to_sage
 
-def slz_rat_poly_of_int_to_int_poly_of_int(ratPolyOfInt):
-    pass
-# End slz_ratPoly_of_int_to_int_poly_of_int
+def slz_rat_poly_of_int_to_poly_for_coppersmith(ratPolyOfInt, 
+                                                precision,
+                                                targetHardnessToRound,
+                                                variable1,
+                                                variable2):
+    """
+    Creates a new polynomial with integer coefficients for use with the
+    Coppersmith method.
+    A the same time it computes :
+    - 2^K (N);
+    - 2^k
+    - lcm
+    """
+    # Create a new integer polynomial ring.
+    IP = PolynomialRing(ZZ, name=str(variable1) + "," + str(variable2))
+    # Coefficients are issued in the increasing power order.
+    ratPolyCoefficients = ratPolyOfInt.coefficients()
+    # Build the list of number we compute the lcmm of.
+    coefficientDenominators = sro_denominators(ratPolyCoefficients)
+    coefficientDenominators.append(2^precision)
+    coefficientDenominators.append(2^(targetHardnessToRound + 1))
+    leastCommonMultiple = sro_lcmm(coefficientDenominators)
+    # Compute the lcm
+    leastCommonMultiple = sro_lcmm(coefficientDenominators)
+    # Compute the expression corresponding to the new polynomial
+    coefficientNumerators =  sro_numerators(ratPolyCoefficients)
+    print coefficientNumerators
+    polynomialExpression = 0
+    power = 0
+    # Iterate over two lists at the same time, stop when the shorter is
+    # exhausted.
+    for numerator, denominator in \
+                            zip(coefficientNumerators, coefficientDenominators):
+        multiplicator = leastCommonMultiple / denominator 
+        newCoefficient = numerator * multiplicator
+        polynomialExpression += newCoefficient * variable1^power
+        power +=1
+    polynomialExpression += - variable2
+    return (IP(polynomialExpression),
+            leastCommonMultiple / 2^precision, # 2^K or N.
+            leastCommonMultiple / 2 ^(targetHardnessToRound + 1), # tBound
+            leastCommonMultiple)
+        
+# End slz_ratPoly_of_int_to_poly_for_coppersmith
 
 def slz_rat_poly_of_rat_to_rat_poly_of_int(ratPolyOfRat, 
                                           precision):
