commit 2669308a21cd6e23dcebd3dfdedc06bef7605059
Author: Serge Torres <Serge.Torres@ens-lyon.fr>
Date:   Mon Feb 15 22:03:57 2016 +0100

    Fixed: when the error functions return intervals or do not return anything.

diff --git a/src/functions_for_cvp.sage b/src/functions_for_cvp.sage
index e90c40b..30d01e6 100644
--- a/src/functions_for_cvp.sage
+++ b/src/functions_for_cvp.sage
@@ -521,6 +521,22 @@ def cvp_extra_function_scaling_exp(floatBasis,
     return extraScalingExp
 # End cvp_extra_function_scaling_exp.
 #
+def cvp_filter_out_undefined_image(initialPointList, func):
+    """
+    Fom the initial list and function, built a list of points which have a
+    defined image.
+    """
+    finalPointsList = []
+    for iterPoint in initialPointList:
+        try:
+            finalPointsList.append(func(iterPoint))
+            #print "cfoui - Point", iterPoint, "done."
+        except ValueError:
+            pass
+            #print "cfoui - Point", iterPoint, "failed."
+    return finalPointsList
+# End    cvp_filter_out_undefined_image
+ 
 def cvp_float_basis(monomialsList, pointsList, realField):
     """
     For a given monomials list and points list, compute the floating-point
@@ -549,15 +565,16 @@ def cvp_float_vector_for_approx(func,
     ## Some local variables.
     basisPointsNum = len(basisPointsList)
     #
+    floatVector = vector(realField, basisPointsNum)
     ##
-    vVect = vector(realField, basisPointsNum)
     for vIndex in xrange(0,basisPointsNum):
-        vVect[vIndex] = \
-            func(basisPointsList[vIndex])
-    return vVect
+        ### We assume the all for all points their image is defined.
+        floatVector[vIndex] = \
+                func(basisPointsList[vIndex])
+    return floatVector
 # End cvp_float_vector_for_approx.
 #
-def cvp_func_abs_max_for_points(func, pointsList):
+def cvp_func_abs_max_for_points(func, pointsList, realField):
     """
     Compute the maximum absolute value of a function for a list of 
     points.
@@ -572,14 +589,19 @@ def cvp_func_abs_max_for_points(func, pointsList):
         return None
     #
     for pt in pointsList:
-        evalDict[abs(func(pt))] = pt
+        try:
+            evalDict[abs(realField(func(pt)))] = realField(pt)
+            #print "cfamfp - point:", realField(pt) , "- image:", abs(realField(func(pt)))
+        except ValueError:
+            pass
     maxAbs = max(evalDict.keys())
+    #print "cfamfp - maxAbs:", maxAbs, evalDict[maxAbs]
     return (evalDict[maxAbs], maxAbs)
 # End cvp_func_abs_max_for_points
 #
 def cvp_hkz_reduce(intBasis):
     """
-    Thin and simplistic wrapper the HKZ function of the FP_LLL module.
+    Thin and simplistic wrapper on the HKZ function of the FP_LLL module.
     """
     fplllIntBasis = FP_LLL(intBasis)
     fplllIntBasis.HKZ()
@@ -719,6 +741,41 @@ def cvp_polynomial_error_func_maxis(funcSa,
         pobyso_clear_obj(errorFuncSo)
         return None
     #print "cpefa: error function in Sollya OK."
+    ## Evaluate the error function at both bounds, it may be usefull, if
+    #  the error function is monotonous
+    ## Lower bound stuff.
+    lowerBoundSo = pobyso_constant_sa_so(lowerBoundSa)
+    if pobyso_is_error_so_sa(lowerBoundSo):
+        pobyso_clear_obj(errorFuncSo)
+        pobyso_clear_obj(lowerBoundSo)
+        return None
+    errFuncAtLbSa = pobyso_evaluate_so_sa(errorFuncSo, lowerBoundSo)
+    pobyso_clear_obj(lowerBoundSo)
+    if errFuncAtLbSa is None:
+        pobyso_clear_obj(errorFuncSo)
+        return None
+    ## The result of the evaluation can be an interval.
+    try:
+        errFuncAtLbSa = errFuncAtLbSa.center()
+    except:
+        errFuncAtLbSa = errFuncAtLbSa
+    #print "cpefa: errFuncAtLbSa:", errFuncAtLbSa
+    ## Upper bound stuff.
+    upperBoundSo = pobyso_constant_sa_so(upperBoundSa)
+    if pobyso_is_error_so_sa(upperBoundSo):
+        pobyso_clear_obj(errorFuncSo)
+        pobyso_clear_obj(upperBoundSo)
+        return None
+    errFuncAtUbSa = pobyso_evaluate_so_sa(errorFuncSo, upperBoundSo)
+    pobyso_clear_obj(upperBoundSo)
+    if errFuncAtUbSa is None:
+        return None
+    ## The result of the evaluation can be an interval.
+    try:
+        errFuncAtUbSa = errFuncAtUbSa.center()
+    except:
+        errFuncAtUbSa = errFuncAtUbSa
+    #print "cpefa: errFuncAtUbSa:", errFuncAtUbSa
     ## Compute the derivative.
     diffErrorFuncSo = pobyso_diff_so_so(errorFuncSo)
     pobyso_clear_obj(errorFuncSo)
@@ -768,10 +825,20 @@ def cvp_polynomial_error_func_maxis(funcSa,
         #print "cpefa:", ; pobyso_autoprint(errorFuncMaxisSo)
         ##### The findzeros functions returns intervals (ranges).
         errorFuncRangeMaxisSa = pobyso_range_list_so_sa(errorFuncMaxisSo)
+        #print "cpefa:", errorFuncRangeMaxisSa
         pobyso_clear_obj(errorFuncMaxisSo)
         errorFuncMaxisSa = []
-        for interval in errorFuncRangeMaxisSa:
-            errorFuncMaxisSa.append(interval.center())
+        if len(errorFuncRangeMaxisSa) != 0:
+            for interval in errorFuncRangeMaxisSa:
+                errorFuncMaxisSa.append(interval.center())
+            #print "cpefa:", errorFuncMaxisSa
+        else: # The error function is monotonous. It reaches its maximum
+              # at either of the bounds.
+              errFuncMaxAtBounds = max(abs(errFuncAtLbSa), abs(errFuncAtUbSa))
+              if errFuncMaxAtBounds == abs(errFuncAtLbSa):
+                  errorFuncMaxisSa.append(lowerBoundSa)
+              else:
+                  errorFuncMaxisSa.append(upperBoundSa)
     pobyso_clear_obj(diffErrorFuncSo)
     pobyso_clear_obj(intervalSo)
     ## If required, convert the numbers to rational numbers.
