Opened 2 years ago

Last modified 10 months ago

#24536 new defect

find_local_maximum/minimum() fails with expressions containing complex numbers

Reported by: rws Owned by:
Priority: major Milestone: sage-8.2
Component: symbolics Keywords:
Cc: Merged in:
Authors: Reviewers:
Report Upstream: N/A Work issues:
Branch: Commit:
Dependencies: Stopgaps:

Description (last modified by rws)

sage: find_local_maximum(abs(x+I),-1,1)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-3-f0919e050ec5> in <module>()
----> 1 find_local_maximum(abs(x+I),-Integer(1),Integer(1))

/home/ralf/sage/src/sage/misc/lazy_import.pyx in sage.misc.lazy_import.LazyImport.__call__ (build/cythonized/sage/misc/lazy_import.c:3703)()
    352             True
    353         """
--> 354         return self.get_object()(*args, **kwds)
    355 
    356     def __repr__(self):

/home/ralf/sage/local/lib/python2.7/site-packages/sage/numerical/optimize.pyc in find_local_maximum(f, a, b, tol, maxfun)
    143     """
    144     try:
--> 145         return f.find_local_maximum(a=a, b=b, tol=tol, maxfun=maxfun)
    146     except AttributeError:
    147         pass

/home/ralf/sage/src/sage/symbolic/expression.pyx in sage.symbolic.expression.Expression.find_local_maximum (build/cythonized/sage/symbolic/expression.cpp:66056)()
  11680             (0.561090323458081..., 0.857926501456...)
  11681         """
> 11682         minval, x = (-self).find_local_minimum(a, b, var=var, tol=tol,
  11683                                                      maxfun=maxfun)
  11684         return -minval, x

/home/ralf/sage/src/sage/symbolic/expression.pyx in sage.symbolic.expression.Expression.find_local_minimum (build/cythonized/sage/symbolic/expression.cpp:66379)()
  11739         if var is None:
  11740             var = self.default_variable()
> 11741         return find_local_minimum(self._fast_float_(var),
  11742                                         a=a, b=b, tol=tol, maxfun=maxfun )
  11743 

/home/ralf/sage/src/sage/symbolic/expression.pyx in sage.symbolic.expression.Expression._fast_float_ (build/cythonized/sage/symbolic/expression.cpp:66543)()
  11762         """
  11763         from sage.symbolic.expression_conversions import fast_float
> 11764         return fast_float(self, *vars)
  11765 
  11766     def _fast_callable_(self, etb):

/home/ralf/sage/local/lib/python2.7/site-packages/sage/symbolic/expression_conversions.pyc in fast_float(ex, *vars)
   1572         1.4142135623730951
   1573     """
-> 1574     return FastFloatConverter(ex, *vars)()
   1575 
   1576 #################

/home/ralf/sage/local/lib/python2.7/site-packages/sage/symbolic/expression_conversions.pyc in __call__(self, ex)
    215             if getattr(self, 'use_fake_div', False) and (operator is _operator.mul or operator is mul_vararg):
    216                 div = self.get_fake_div(ex)
--> 217                 return self.arithmetic(div, div.operator())
    218             return self.arithmetic(ex, operator)
    219         elif operator in relation_operators:

/home/ralf/sage/local/lib/python2.7/site-packages/sage/symbolic/expression_conversions.pyc in arithmetic(self, ex, operator)
   1513         operands = ex.operands()
   1514         if operator is _operator.neg:
-> 1515             return operator(self(operands[0]))
   1516 
   1517         from sage.rings.all import Rational

/home/ralf/sage/local/lib/python2.7/site-packages/sage/symbolic/expression_conversions.pyc in __call__(self, ex)
    224             return self.tuple(ex)
    225         else:
--> 226             return self.composition(ex, operator)
    227 
    228     def get_fake_div(self, ex):

/home/ralf/sage/local/lib/python2.7/site-packages/sage/symbolic/expression_conversions.pyc in composition(self, ex, operator)
   1547         """
   1548         f = operator
-> 1549         g = [self(_) for _ in ex.operands()]
   1550         try:
   1551             return f(*g)

/home/ralf/sage/local/lib/python2.7/site-packages/sage/symbolic/expression_conversions.pyc in __call__(self, ex)
    216                 div = self.get_fake_div(ex)
    217                 return self.arithmetic(div, div.operator())
--> 218             return self.arithmetic(ex, operator)
    219         elif operator in relation_operators:
    220             return self.relation(ex, operator)

/home/ralf/sage/local/lib/python2.7/site-packages/sage/symbolic/expression_conversions.pyc in arithmetic(self, ex, operator)
   1519             from sage.functions.all import sqrt
   1520             return sqrt(self(operands[0]))
-> 1521         fops = map(self, operands)
   1522         if operator == add_vararg:
   1523             operator = _operator.add

/home/ralf/sage/local/lib/python2.7/site-packages/sage/symbolic/expression_conversions.pyc in __call__(self, ex)
    206         except TypeError as err:
    207             if 'self must be a numeric expression' not in err.args:
--> 208                 raise err
    209 
    210         operator = ex.operator()

TypeError: unable to coerce to a real number

The rethrown error comes from an attempt to do float(I).

The find_local functions use FastFloatConverter to compute values.

Change History (6)

comment:1 Changed 2 years ago by rws

  • Description modified (diff)

comment:2 Changed 2 years ago by rws

Apparently "Float" literally means Python (real) "float" not floating-point. Of course then expressions containing I raise errors, even if the outcome is real. The original case was the usage by find_local_maximum---so that never worked, and the restriction was undocumented.

comment:3 Changed 2 years ago by rws

  • Description modified (diff)
  • Summary changed from FastFloatConverter fails to convert complex I to find_local_maximum/minimum() fails with expressions containing complex numbers

comment:4 Changed 2 years ago by rws

The documentation of fast_float states

def fast_float(ex, *vars):
    """
    Returns an object which provides fast floating point evaluation of
    the symbolic expression *ex*.

but

sage: from sage.symbolic.expression_conversions import fast_float
sage: ff = fast_float(abs(x+I))
/home/ralf/sage/local/lib/python2.7/site-packages/sage/symbolic/expression_conversions.py:1574: DeprecationWarning: Substitution using function-call syntax and unnamed arguments is deprecated and will be removed from a future release of Sage; you can use named arguments instead, like EXPR(x=..., y=...)
See http://trac.sagemath.org/5930 for details.
  return FastFloatConverter(ex, *vars)()

gives the ticket error.

comment:5 Changed 2 years ago by rws

Relevant: #5572. Somewhat related: #13559, #16899.

comment:6 Changed 10 months ago by jsrn

Note that changing the call from find_local_maximum(abs(x+I),-1,1) to

find_local_maximum(lambda x: abs(x+I),-1,1)

Then everything works fine.

Note: See TracTickets for help on using tickets.