Repository: sympy/sympy

Issue:
Undefined Functions should not use the evalf name lookup scheme
```
If I run sympy.S("ceil(2.3)").evalf() with sympy 0.7.1 then I get 3.  However, if I run the same using sympy 0.7.2 then I get an AttributeError (see below).  I discovered that switching to use ceiling() instead of ceil() works, but I have no idea why ceil() disappeared in the first place.  Someone in IRC told me that the AttributeError was not the correct behaviour for 0.7.2 either.

In [32]: S("ceil(2.3)").evalf()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-32-82d9887af7f2> in <module>()
----> 1 S("ceil(2.3)").evalf()

/home/rob/tmp/sympy-install/lib/python2.7/site-packages/sympy/core/sympify.pyc in sympify(a, locals, convert_xor, strict, rational)
    176     try:
    177         a = a.replace('\n', '')
--> 178         expr = parse_expr(a, locals or {}, rational, convert_xor)
    179     except (TokenError, SyntaxError):
    180         raise SympifyError('could not parse %r' % a)

/home/rob/tmp/sympy-install/lib/python2.7/site-packages/sympy/parsing/sympy_parser.pyc in parse_expr(s, local_dict, rationalize, convert_xor)
    160 
    161     code = _transform(s.strip(), local_dict, global_dict, rationalize, convert_xor)
--> 162     expr = eval(code, global_dict, local_dict) # take local objects in preference
    163 
    164     if not hit:

<string> in <module>()

/home/rob/tmp/sympy-install/lib/python2.7/site-packages/sympy/core/symbol.pyc in __call__(self, *args)
    111     def __call__(self, *args):
    112         from function import Function
--> 113         return Function(self.name)(*args)
    114 
    115     def as_real_imag(self, deep=True, **hints):

/home/rob/tmp/sympy-install/lib/python2.7/site-packages/sympy/core/function.pyc in __new__(cls, *args, **options)
    596         args = map(sympify, args)
    597         result = super(AppliedUndef, cls).__new__(cls, *args, **options)
--> 598         result.nargs = len(args)
    599         return result
    600 

AttributeError: 'Float' object has no attribute 'nargs'
```

Original issue for #6938: http://code.google.com/p/sympy/issues/detail?id=3839
Original author: https://code.google.com/u/113990760755850617280/


Discussion:

Patch:
diff --git a/.travis.yml b/.travis.yml
index 9ab2d5cde0..73ece9ff9d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -249,7 +249,7 @@ before_install:
             conda install matchpy;
         fi
     elif [ "$TRAVIS_PYTHON_VERSION" != "pypy" ]; then
-        pip list | grep "numpy" && pip uninstall -y numpy;
+        pip list --format=legacy | grep "numpy" && pip uninstall -y numpy;
     fi
 
 install:
@@ -267,9 +267,7 @@ install:
     # The install cycle below is to test installation on systems without setuptools.
       pip uninstall -y setuptools;
       python -We:invalid setup.py install;
-      pip install --upgrade --force-reinstall pip==9.0.3;
       pip uninstall -y sympy;
-      pip install --upgrade pip;
       pip install --upgrade setuptools;
     fi
     python -We:invalid -m compileall -f sympy/;
diff --git a/doc/src/modules/physics/mechanics/autolev_parser.rst b/doc/src/modules/physics/mechanics/autolev_parser.rst
index 252f64e598..3f7edd3e64 100644
--- a/doc/src/modules/physics/mechanics/autolev_parser.rst
+++ b/doc/src/modules/physics/mechanics/autolev_parser.rst
@@ -153,447 +153,3 @@ and manipulations like ``trigsimp()``, ``expand()``, ``evalf()`` etc for
 getting outputs similar to Autolev.
 Refer to the `SymPy Tutorial <http://docs.sympy.org/latest/tutorial/index.html>`_
 to know more about these.
-
-.. _gotchas_autolev:
-
-Gotchas
-=======
-
-- Don't use variable names that conflict with Python's reserved words.
-  This is one example where this is violated:
-
-  .. code-block:: none
-
-     Autolev Code
-     ------------
-     LAMBDA = EIG(M)
-
-  .. code-block:: python
-
-     SymPy Code
-     ----------
-     lambda = sm.Matrix([i.evalf() for i in (m).eigenvals().keys()])
-
-------------------------------------------------------------------------
-
-- Make sure that the names of vectors and scalars are different.
-  Autolev treats these differently but these will get overwritten in Python.
-  The parser currently allows the names of bodies and scalars/vectors to
-  coincide but doesn't do this between scalars and vectors.
-  This should probably be changed in the future.
-
-  .. code-block:: none
-
-     Autolev Code
-     ------------
-     VARIABLES X,Y
-     FRAMES A
-     A> = X*A1> + Y*A2>
-     A = X+Y
-
-  .. code-block:: python
-
-     SymPy Code
-     ----------
-     x, y = me.dynamicsymbols('x y')
-     frame_a = me.ReferenceFrame('a')
-     a = x*frame_a.x + y*frame_a.y
-     a = x + y
-     # Note how frame_a is named differently so it doesn't cause a problem.
-     # On the other hand, 'a' gets rewritten from a scalar to a vector.
-     # This should be changed in the future.
-
-
-------------------------------------------------------------------------
-
-- When dealing with Matrices returned by functions, one must check the
-  order of the values as they may not be the same as in Autolev. This is
-  especially the case for eigenvalues and eigenvetors.
-  
-  .. code-block:: none
-
-     Autolev Code
-     ------------
-     EIG(M, E1, E2)
-     % -> [5; 14; 13]
-     E2ROW = ROWS(E2, 1)
-     EIGVEC> = VECTOR(A, E2ROW)
-
-  .. code-block:: python
-
-     SymPy Code
-     ---------- 
-     e1 = sm.Matrix([i.evalf() for i in m.eigenvals().keys()])
-     # sm.Matrix([5;13;14]) different order
-     e2 = sm.Matrix([i[2][0].evalf() for i in m.eigenvects()]).reshape(m.shape[0], m.shape[1])
-     e2row = e2.row(0)
-     # This result depends on the order of the vectors in the eigenvecs.
-     eigenvec = e2row[0]*a.x + e2row[1]*a.y + e2row[2]*a.y
-
-------------------------------------------------------------------------
-
-- When using ``EVALUATE``, use something like ``90*UNITS(deg,rad)`` for 
-  angle substitutions as radians are the default in SymPy.
-  You could also add ``np.deg2rad()`` directly in the SymPy code.
-  
-  This need not be done for the output code (generated on parsing the
-  ``CODE`` commands) as the parser takes care of this when ``deg`` units
-  are given in the ``INPUT`` declarations. 
-  
-  The ``DEGREES`` setting, on the other hand, works only in some cases like 
-  in ``SIMPROT`` where an angle is expected.
-
-  .. code-block:: none
-
-     Autolev Code
-     ------------
-     A> = Q1*A1> + Q2*A2>
-     B> = EVALUATE(A>, Q1:30*UNITS(DEG,RAD))
-
-  .. code-block:: python
-  
-     SymPy Code
-     ----------
-     a = q1*a.frame_a.x + q2*frame_a.y
-     b = a.subs({q1:30*0.0174533})
-     # b = a.subs({q1:np.deg2rad(30)}
-
-------------------------------------------------------------------------
-
-- Most of the Autolev settings have not been parsed and have no effect on the parser.
-  The only ones that work somewhat are ``COMPLEX`` and ``DEGREES``.
-  It is advised to look into alternatives to these in SymPy and Python.
-
-------------------------------------------------------------------------
-
-- The ``REPRESENT`` command is not supported.
-  Use the ``MATRIX``, ``VECTOR`` or ``DYADIC`` commands instead.
-  Autolev 4.1 suggests these over ``REPRESENT`` as well while still allowing
-  it but the parser doesn't parse it.
-
-------------------------------------------------------------------------
-
-- Do not use variables declarations of the type ``WO{3}RD{2,4}``.
-  The parser can only handle one variable name followed by one pair
-  of curly braces and any number of ``'`` s.
-  You would have to declare all the cases manually if you want to achieve
-  something like ``WO{3}RD{2,4}``.
-
-------------------------------------------------------------------------
-
-- The parser can handle normal versions of most commands but it may not
-  parse functions with Matrix arguments properly in most cases.
-  Eg:
-
-  ``M=COEF([E1;E2],[U1,U2,U3])``
-
-  This would compute the coefficients of ``U1``, ``U2`` and ``U3`` in ``E1``
-  and ``E2``. It is preferable to manually construct a Matrix using the 
-  regular versions of these commands.
-
-  .. code-block:: none
-
-     Autolev Code
-     ------------
-     % COEF([E1;E2],[U1,U2,U3])
-     M = [COEF(E1,U1),COEF(E1,U2),COEF(E1,U3) &
-         ;COEF(E2,U1),COEF(E2,U2),COEF(E2,U3)]    
-
-------------------------------------------------------------------------
-
-- ``MOTIONVARIABLE`` declarations must be used for the generalized coordinates
-  and speeds and all other variables must be declared in regular
-  ``VARIABLE`` declarations.
-  The parser requires this to distinguish between them to pass the correct
-  parameters to the Kane's method object.
-  
-  It is also preferred to always declare the speeds corresponding to the
-  coordinates and to pass in the kinematic differential equations.
-  The parser is able to handle some cases where this isn't the case by
-  introducing some dummy variables of its own but SymPy on its own
-  does require them.
-  
-  Also note that older Autolev declarations like ``VARIABLES U{3}'`` are not
-  supported either.
-
-  .. code-block:: none
-
-     Autolev Code
-     ------------
-     MOTIONVARIABLES' Q{2}', U{2}'
-     % ----- OTHER LINES ----
-     Q1' = U1
-     Q2' = U2
-     ----- OTHER LINES ----
-     ZERO = FR() + FRSTAR()
-
-  .. code-block:: python
-
-     SymPy Code
-     ----------
-     q1, q2, u1, u2 = me.dynamicsymbols('q1 q2 u1 u2')
-     q1d, q2d, u1d, u2d = me.dynamicsymbols('q1 q2 u1 u2', 1)
-     
-     # ------- other lines -------
-     
-     kd_eqs = [q1d - u1, q2d - u2]
-     kane = me.KanesMethod(frame_n, q_ind=[q1,q2], u_ind=[u1, u2], kd_eqs = kd_eqs)
-     fr, frstar = kane.kanes_equations([particle_p, particle_r], forceList)
-     zero = fr+frstar
-
-------------------------------------------------------------------------
-
-- Need to change ``me.dynamicsymbols._t`` to ``me.dynamicsymbols('t')`` for
-  all occurences of it in the Kane's equations. For example have a look at
-  line 10 of this `spring damper example <https://github.com/sympy/sympy/blob/master/sympy/parsing/autolev/test_examples/mass_spring_damper.py>`_.
-  This equation is used in forming the Kane's equations so we need to
-  change ``me.dynamicsymbols._t`` to ``me.dynamicsymbols('t')`` in this case.
-  
-  The main reason that this needs to be done is because PyDy
-  requires time dependent specifieds to be explicitly laid out while
-  Autolev simply takes care of the stray time variables in the equations
-  by itself.
-  
-  The problem is that PyDy's System class does not accept
-  ``dynamicsymbols._t`` as a specified. 
-  This change is not actually ideal so a better solution should be figured
-  out in the future.
-
-------------------------------------------------------------------------
-
-- The parser creates SymPy ``symbols`` and ``dynamicsymbols`` by parsing
-  variable declarations in the Autolev Code.
-  
-  For intermediate expressions which are directly initialized the parser
-  does not create SymPy symbols. It just assigns them to the expression.
-  
-  On the other hand, when a declared variable is assigned to an expression,
-  the parser stores the expression against the variable in a dictionary so 
-  as to not reassign it to a completely different entity. This constraint 
-  is due to the inherent nature of Python and how it differs from a language
-  like Autolev.
-  
-  Also, Autolev seems to be able to assume whether to use a variable or the
-  rhs expression that variable has been assigned to in equations even
-  without an explicit ``RHS()`` call in some cases.
-  For the parser to work correctly however, it is better to use ``RHS()``
-  wherever a variable's rhs expression is meant to be used.
-
-  .. code-block:: none
-
-     Autolev Code
-     ------------
-     VARIABLES X, Y
-     E = X + Y
-     X = 2*Y
-     
-     RHS_X = RHS(X)
-     
-     I1 = X
-     I2 = Y
-     I3 = X + Y
-     
-     INERTIA B,I1,I2,I3
-     % -> I_B_BO>> = I1*B1>*B1> + I2*B2>*B2> + I3*B3>*B3>
-
-  .. code-block:: python
-
-     SymPy Code
-     ----------
-     x,y = me.dynamicsymbols('x y')
-     e = x + y  # No symbol is made out of 'e'
-     
-     # an entry like {x:2*y} is stored in an rhs dictionary
-     
-     rhs_x = 2*y
-     
-     i1 = x  # again these are not made into SymPy symbols
-     i2 = y
-     i3 = x + y
-     
-     body_b.inertia = (me.inertia(body_b_f, i1, i2, i3), b_cm)
-     # This prints as:
-     # x*b_f.x*b_f.x + y*b_f.y*b_f.y + (x+y)*b_f.z*b_f.z
-     # while Autolev's output has I1,I2 and I3 in it.
-     # Autolev however seems to know when to use the RHS of I1,I2 and I3
-     # based on the context.
-  
-------------------------------------------------------------------------
-
-- This is how the ``SOLVE`` command is parsed:
-
-  .. code-block:: none
-
-     Autolev Code
-     ------------
-     SOLVE(ZERO,X,Y)
-     A = RHS(X)*2 + RHS(Y)
-
-  .. code-block:: python
-
-     SymPy Code
-     ----------
-     print(sm.solve(zero,x,y))
-     # Behind the scenes the rhs of x
-     # is set to sm.solve(zero,x,y)[x].
-     a = sm.solve(zero,x,y)[x]*2 + sm.solve(zero,x,y)[y]
-     
-  The indexing like ``[x]`` and ``[y]`` doesn't always work so you might want to
-  look at the underlying dictionary that solve returns and index it correctly.
-  
-------------------------------------------------------------------------
-
-- Inertia declarations and Inertia functions work somewhat differently in
-  the context of the parser. This might be hard to understand at first
-  but this had to be done to bridge the gap due to the differences in
-  SymPy and Autolev. Here are some points about them:
-
-  1. Inertia declarations (``INERTIA B,I1,I2,I3``) set the inertias of rigid
-  bodies.
-  
-  2. Inertia setters of the form ``I_C_D>> = expr`` however, set the inertias
-  only when C is a body. If C is a particle then ``I_C_D>> = expr``
-  simply parses to ``i_c_d = expr`` and ``i_c_d`` acts like a regular variable.
-  
-  3. When it comes to inertia getters (``I_C_D>>`` used in an expression or
-  ``INERTIA`` commands), these MUST be used with the ``EXPRESS`` command
-  to specify the frame as SymPy needs this information to compute the
-  inertia dyadic.
-
-  .. code-block:: none
-
-     Autolev Code
-     ------------
-     INERTIA B,I1,I2,I3
-     I_B_BO>> = X*A1>*A1> + Y*A2>*A2>  % Parser will set the inertia of B
-     I_P_Q>> = X*A1>*A1> + Y^2*A2>*A2> % Parser just parses it as i_p_q = expr
-     
-     E1 = 2*EXPRESS(I_B_O>>,A)
-     E2 =  I_P_Q>>
-     E3 = EXPRESS(I_P_O>>,A)
-     E4 = EXPRESS(INERTIA(O),A)
-     
-     % In E1 we are using the EXPRESS command with I_B_O>> which makes
-     % the parser and SymPy compute the inertia of Body B about point O.
-     
-     % In E2 we are just using the dyadic object I_P_Q>> (as I_P_Q>> = expr
-     % doesn't act as a setter) defined above and not asking the parser 
-     % or SymPy to compute anything.
-     
-     % E3 asks the parser to compute the inertia of P about point O.
-     
-     % E4 asks the parser to compute the inertias of all bodies wrt about O.
-
-------------------------------------------------------------------------
-
-- In an inertia declaration of a body, if the inertia is being set about
-  a point other than the center of mass, one needs to make sure that
-  the position vector setter for that point and the center of mass appears
-  before the inertia declaration as SymPy will throw an error otherwise.
-
-  .. code-block:: none
-
-     Autolev Code
-     ------------
-     P_SO_O> = X*A1>
-     INERTIA S_(O) I1,I2,I3
-
-------------------------------------------------------------------------
-
-- Note that all Autolev commands have not been implemented. The parser
-  now covers the important ones in their basic forms. If you are doubtful
-  whether a command is included or not, please have a look at `this file <https://github.com/sympy/sympy/blob/master/sympy/parsing/autolev/_listener_autolev_antlr.py>`_
-  in the source code. Search for "<command>" to verify this. Looking at the
-  code for the specific command will also give an idea about what form it
-  is expected to work in.
-
-.. _issues:
-
-Limitations and Issues
-======================
-
-- A lot of the issues have already been discussed in the Gotchas section.
-  Some of these are:
-
-  - Vector names coinciding with scalar names are overwritten in Python.
-  - Some convenient variable declarations aren't parsed.
-  - Some convenient forms of functions to return matrices aren't parsed.
-  - Settings aren't parsed.
-  - symbols and rhs expressions work very differently in Python which might
-    cause undesirable results.
-  - Dictionary indexing for the parsed code of the ``SOLVE`` command is 
-    not proper in many cases.
-  - Need to change ``dynamicsymbols._t`` to ``dynamicsymbols('t')`` for the
-    PyDy simulation code to work properly.
-
-Here are some other ones:
-
-- Eigenvectors do not seem to work as expected. The values in Autolev and SymPy
-  are not the same in many cases.
-
-- Block matrices aren't parsed by the parser. It would actually be easier
-  to make a change in SymPy to allow matrices to accept other matrices for
-  arguments.
-
-- The SymPy equivalent of the ``TAYLOR`` command ``.series()`` does not work
-  with ``dynamicsymbols()``.
-
-- Only ``DEPENDENT`` constraints are currently parsed. Need to parse
-  ``AUXILIARY`` constraints as well. This should be done soon as it isn't
-  very difficult.
-
-- None of the energy and momentum functions are parsed right now. It would
-  be nice to get these working as well. Some changes should probably be made
-  to SymPy. For instance, SymPy doesn't have a function equivalent to ``NICHECK()``.
-
-- The numerical integration parts work properly only in the case of the
-  ``KANE`` command with no arguments. Things like ``KANE(F1,F2)`` do not currently
-  work.
-
-- Also, the PyDy numerical simulation code works only for cases where the
-  matrix say ``ZERO = FR() + FRSTAR()`` is solved for. It doesn't work well when the
-  matrix has some other equations plugged in as well. One hurdle
-  faced in achieving this was that PyDy's System class automatically takes
-  in the ``forcing_full`` and ``mass_matrix_full`` and solves them without giving the
-  user the flexibility to specify the equations. It would be nice to add
-  this functionality to the System class.
-
-
-.. _future_improvements:
-
-Future Improvements
-===================
-
-1. Completing Dynamics Online
------------------------------
-The parser has been built by referring to and parsing codes from the
-`Autolev Tutorial <http://web.mae.ufl.edu/~fregly/PDFs/autolev_tutorial.pdf>`_
-and the book *Dynamics Online: Theory and Implementation Using Autolev*.
-Basically, the process involved going through each of these codes,
-validating the parser results and improving the rules if required
-to make sure the codes parsed well.
-
-The parsed codes of these are available on GitLab `here <https://gitlab.com/sympy/autolev-test-examples>`_.
-The repo is private so access needs to be requested.
-As of now, most codes till Chapter 4 of *Dynamics Online* have been parsed. 
-
-Completing all the remaining codes of the book (namely, *2-10*, *2-11*, *rest
-of Ch4*, *Ch5* and *Ch6* (less important) ) would make the parser more complete.
-
-
-2. Fixing Issues
-----------------
-The second thing to do would be to go about fixing the problems described 
-above in the :ref:`Gotchas <gotchas_autolev>` and :ref:`Limitations and Issues <issues>` 
-sections in order of priority and ease. Many of these require changes
-in the parser code while some of these are better fixed by adding some
-functionality to SymPy.
-
-
-3. Switching to an AST
-----------------------
-The parser is currently built using a kind of Concrete Syntax Tree (CST) 
-using the `ANTLR <http://www.antlr.org/>`_ framework. It would be ideal to switch from a CST to an
-Abstract Syntax Tree (AST). This way, the parser code will be independent
-of the ANTLR grammar which makes it a lot more flexible. It would also be
-easier to make changes to the grammar and the rules of the parser.
diff --git a/sympy/core/function.py b/sympy/core/function.py
index 97cc9d9187..9c4453ab50 100644
--- a/sympy/core/function.py
+++ b/sympy/core/function.py
@@ -510,8 +510,11 @@ def is_commutative(self):
 
     def _eval_evalf(self, prec):
         # Lookup mpmath function based on name
-        fname = self.func.__name__
         try:
+            if isinstance(self.func, UndefinedFunction):
+                # Shouldn't lookup in mpmath but might have ._imp_
+                raise AttributeError
+            fname = self.func.__name__
             if not hasattr(mpmath, fname):
                 from sympy.utilities.lambdify import MPMATH_TRANSLATIONS
                 fname = MPMATH_TRANSLATIONS[fname]
diff --git a/sympy/physics/continuum_mechanics/beam.py b/sympy/physics/continuum_mechanics/beam.py
index 01aef6d4da..47363580aa 100644
--- a/sympy/physics/continuum_mechanics/beam.py
+++ b/sympy/physics/continuum_mechanics/beam.py
@@ -12,9 +12,6 @@
 from sympy.core import sympify
 from sympy.integrals import integrate
 from sympy.series import limit
-from sympy.plotting import plot
-from sympy.external import import_module
-from sympy.utilities.decorator import doctest_depends_on
 
 
 class Beam(object):
@@ -1128,297 +1125,6 @@ def max_deflection(self):
         else:
             return None
 
-    def plot_shear_force(self, subs=None):
-        """
-        Returns a plot for Shear force present in the Beam object.
-
-        Parameters
-        ==========
-        subs : dictionary
-            Python dictionary containing Symbols as key and their
-            corresponding values.
-
-        Examples
-        ========
-        There is a beam of length 8 meters. A constant distributed load of 10 KN/m
-        is applied from half of the beam till the end. There are two simple supports
-        below the beam, one at the starting point and another at the ending point
-        of the beam. A pointload of magnitude 5 KN is also applied from top of the
-        beam, at a distance of 4 meters from the starting point.
-        Take E = 200 GPa and I = 400*(10**-6) meter**4.
-
-        Using the sign convention of downwards forces being positive.
-
-        >>> from sympy.physics.continuum_mechanics.beam import Beam
-        >>> from sympy import symbols
-        >>> R1, R2 = symbols('R1, R2')
-        >>> b = Beam(8, 200*(10**9), 400*(10**-6))
-        >>> b.apply_load(5000, 2, -1)
-        >>> b.apply_load(R1, 0, -1)
-        >>> b.apply_load(R2, 8, -1)
-        >>> b.apply_load(10000, 4, 0, end=8)
-        >>> b.bc_deflection = [(0, 0), (8, 0)]
-        >>> b.solve_for_reaction_loads(R1, R2)
-        >>> b.plot_shear_force()
-        Plot object containing:
-        [0]: cartesian line: -13750*SingularityFunction(x, 0, 0) + 5000*SingularityFunction(x, 2, 0)
-        + 10000*SingularityFunction(x, 4, 1) - 31250*SingularityFunction(x, 8, 0)
-        - 10000*SingularityFunction(x, 8, 1) for x over (0.0, 8.0)
-        """
-        shear_force = self.shear_force()
-        if subs is None:
-            subs = {}
-        for sym in shear_force.atoms(Symbol):
-            if sym == self.variable:
-                continue
-            if sym not in subs:
-                raise ValueError('Value of %s was not passed.' %sym)
-        if self.length in subs:
-            length = subs[self.length]
-        else:
-            length = self.length
-        return plot(shear_force.subs(subs), (self.variable, 0, length), title='Shear Force',
-                xlabel='position', ylabel='Value', line_color='g')
-
-    def plot_bending_moment(self, subs=None):
-        """
-        Returns a plot for Bending moment present in the Beam object.
-
-        Parameters
-        ==========
-        subs : dictionary
-            Python dictionary containing Symbols as key and their
-            corresponding values.
-
-        Examples
-        ========
-        There is a beam of length 8 meters. A constant distributed load of 10 KN/m
-        is applied from half of the beam till the end. There are two simple supports
-        below the beam, one at the starting point and another at the ending point
-        of the beam. A pointload of magnitude 5 KN is also applied from top of the
-        beam, at a distance of 4 meters from the starting point.
-        Take E = 200 GPa and I = 400*(10**-6) meter**4.
-
-        Using the sign convention of downwards forces being positive.
-
-        >>> from sympy.physics.continuum_mechanics.beam import Beam
-        >>> from sympy import symbols
-        >>> R1, R2 = symbols('R1, R2')
-        >>> b = Beam(8, 200*(10**9), 400*(10**-6))
-        >>> b.apply_load(5000, 2, -1)
-        >>> b.apply_load(R1, 0, -1)
-        >>> b.apply_load(R2, 8, -1)
-        >>> b.apply_load(10000, 4, 0, end=8)
-        >>> b.bc_deflection = [(0, 0), (8, 0)]
-        >>> b.solve_for_reaction_loads(R1, R2)
-        >>> b.plot_bending_moment()
-        Plot object containing:
-        [0]: cartesian line: -13750*SingularityFunction(x, 0, 1) + 5000*SingularityFunction(x, 2, 1)
-        + 5000*SingularityFunction(x, 4, 2) - 31250*SingularityFunction(x, 8, 1)
-        - 5000*SingularityFunction(x, 8, 2) for x over (0.0, 8.0)
-        """
-        bending_moment = self.bending_moment()
-        if subs is None:
-            subs = {}
-        for sym in bending_moment.atoms(Symbol):
-            if sym == self.variable:
-                continue
-            if sym not in subs:
-                raise ValueError('Value of %s was not passed.' %sym)
-        if self.length in subs:
-            length = subs[self.length]
-        else:
-            length = self.length
-        return plot(bending_moment.subs(subs), (self.variable, 0, length), title='Bending Moment',
-                xlabel='position', ylabel='Value', line_color='b')
-
-    def plot_slope(self, subs=None):
-        """
-        Returns a plot for slope of deflection curve of the Beam object.
-
-        Parameters
-        ==========
-        subs : dictionary
-            Python dictionary containing Symbols as key and their
-            corresponding values.
-
-        Examples
-        ========
-        There is a beam of length 8 meters. A constant distributed load of 10 KN/m
-        is applied from half of the beam till the end. There are two simple supports
-        below the beam, one at the starting point and another at the ending point
-        of the beam. A pointload of magnitude 5 KN is also applied from top of the
-        beam, at a distance of 4 meters from the starting point.
-        Take E = 200 GPa and I = 400*(10**-6) meter**4.
-
-        Using the sign convention of downwards forces being positive.
-
-        >>> from sympy.physics.continuum_mechanics.beam import Beam
-        >>> from sympy import symbols
-        >>> R1, R2 = symbols('R1, R2')
-        >>> b = Beam(8, 200*(10**9), 400*(10**-6))
-        >>> b.apply_load(5000, 2, -1)
-        >>> b.apply_load(R1, 0, -1)
-        >>> b.apply_load(R2, 8, -1)
-        >>> b.apply_load(10000, 4, 0, end=8)
-        >>> b.bc_deflection = [(0, 0), (8, 0)]
-        >>> b.solve_for_reaction_loads(R1, R2)
-        >>> b.plot_slope()
-        Plot object containing:
-        [0]: cartesian line: -8.59375e-5*SingularityFunction(x, 0, 2) + 3.125e-5*SingularityFunction(x, 2, 2)
-        + 2.08333333333333e-5*SingularityFunction(x, 4, 3) - 0.0001953125*SingularityFunction(x, 8, 2)
-        - 2.08333333333333e-5*SingularityFunction(x, 8, 3) + 0.00138541666666667 for x over (0.0, 8.0)
-        """
-        slope = self.slope()
-        if subs is None:
-            subs = {}
-        for sym in slope.atoms(Symbol):
-            if sym == self.variable:
-                continue
-            if sym not in subs:
-                raise ValueError('Value of %s was not passed.' %sym)
-        if self.length in subs:
-            length = subs[self.length]
-        else:
-            length = self.length
-        return plot(slope.subs(subs), (self.variable, 0, length), title='Slope',
-                xlabel='position', ylabel='Value', line_color='m')
-
-    def plot_deflection(self, subs=None):
-        """
-        Returns a plot for deflection curve of the Beam object.
-
-        Parameters
-        ==========
-        subs : dictionary
-            Python dictionary containing Symbols as key and their
-            corresponding values.
-
-        Examples
-        ========
-        There is a beam of length 8 meters. A constant distributed load of 10 KN/m
-        is applied from half of the beam till the end. There are two simple supports
-        below the beam, one at the starting point and another at the ending point
-        of the beam. A pointload of magnitude 5 KN is also applied from top of the
-        beam, at a distance of 4 meters from the starting point.
-        Take E = 200 GPa and I = 400*(10**-6) meter**4.
-
-        Using the sign convention of downwards forces being positive.
-
-        >>> from sympy.physics.continuum_mechanics.beam import Beam
-        >>> from sympy import symbols
-        >>> R1, R2 = symbols('R1, R2')
-        >>> b = Beam(8, 200*(10**9), 400*(10**-6))
-        >>> b.apply_load(5000, 2, -1)
-        >>> b.apply_load(R1, 0, -1)
-        >>> b.apply_load(R2, 8, -1)
-        >>> b.apply_load(10000, 4, 0, end=8)
-        >>> b.bc_deflection = [(0, 0), (8, 0)]
-        >>> b.solve_for_reaction_loads(R1, R2)
-        >>> b.plot_deflection()
-        Plot object containing:
-        [0]: cartesian line: 0.00138541666666667*x - 2.86458333333333e-5*SingularityFunction(x, 0, 3)
-        + 1.04166666666667e-5*SingularityFunction(x, 2, 3) + 5.20833333333333e-6*SingularityFunction(x, 4, 4)
-        - 6.51041666666667e-5*SingularityFunction(x, 8, 3) - 5.20833333333333e-6*SingularityFunction(x, 8, 4)
-        for x over (0.0, 8.0)
-        """
-        deflection = self.deflection()
-        if subs is None:
-            subs = {}
-        for sym in deflection.atoms(Symbol):
-            if sym == self.variable:
-                continue
-            if sym not in subs:
-                raise ValueError('Value of %s was not passed.' %sym)
-        if self.length in subs:
-            length = subs[self.length]
-        else:
-            length = self.length
-        return plot(deflection.subs(subs), (self.variable, 0, length), title='Deflection',
-                xlabel='position', ylabel='Value', line_color='r')
-
-    @doctest_depends_on(modules=('numpy', 'matplotlib',))
-    def plot_loading_results(self, subs=None):
-        """
-        Returns Axes object containing subplots of Shear Force, Bending Moment,
-        Slope and Deflection of the Beam object.
-
-        Parameters
-        ==========
-        subs : dictionary
-            Python dictionary containing Symbols as key and their
-            corresponding values.
-
-        .. note::
-           This method only works if numpy and matplotlib libraries
-           are installed on the system.
-
-        Examples
-        ========
-        There is a beam of length 8 meters. A constant distributed load of 10 KN/m
-        is applied from half of the beam till the end. There are two simple supports
-        below the beam, one at the starting point and another at the ending point
-        of the beam. A pointload of magnitude 5 KN is also applied from top of the
-        beam, at a distance of 4 meters from the starting point.
-        Take E = 200 GPa and I = 400*(10**-6) meter**4.
-
-        Using the sign convention of downwards forces being positive.
-
-        >>> from sympy.physics.continuum_mechanics.beam import Beam
-        >>> from sympy import symbols
-        >>> R1, R2 = symbols('R1, R2')
-        >>> b = Beam(8, 200*(10**9), 400*(10**-6))
-        >>> b.apply_load(5000, 2, -1)
-        >>> b.apply_load(R1, 0, -1)
-        >>> b.apply_load(R2, 8, -1)
-        >>> b.apply_load(10000, 4, 0, end=8)
-        >>> b.bc_deflection = [(0, 0), (8, 0)]
-        >>> b.solve_for_reaction_loads(R1, R2)
-        >>> axes = b.plot_loading_results()
-        """
-        from sympy import lambdify
-        matplotlib = import_module('matplotlib', __import__kwargs={'fromlist':['pyplot']})
-        plt = matplotlib.pyplot
-        numpy = import_module('numpy', __import__kwargs={'fromlist':['linspace']})
-        linspace = numpy.linspace
-
-        length = self.length
-        variable = self.variable
-        if subs is None:
-            subs = {}
-        for sym in self.deflection().atoms(Symbol):
-            if sym == self.variable:
-                continue
-            if sym not in subs:
-                raise ValueError('Value of %s was not passed.' %sym)
-        if self.length in subs:
-            length = subs[self.length]
-        else:
-            length = self.length
-
-        # As we are using matplotlib directly in this method, we need to change SymPy methods
-        # to numpy functions.
-        shear = lambdify(variable, self.shear_force().subs(subs).rewrite(Piecewise), 'numpy')
-        moment = lambdify(variable, self.bending_moment().subs(subs).rewrite(Piecewise), 'numpy')
-        slope = lambdify(variable, self.slope().subs(subs).rewrite(Piecewise), 'numpy')
-        deflection = lambdify(variable, self.deflection().subs(subs).rewrite(Piecewise), 'numpy')
-
-        points = linspace(0, float(length), num=5*length)
-
-        # Creating a grid for subplots with 2 rows and 2 columns
-        fig, axs = plt.subplots(4, 1)
-        # axs is a 2D-numpy array containing axes
-        axs[0].plot(points, shear(points))
-        axs[0].set_title("Shear Force")
-        axs[1].plot(points, moment(points))
-        axs[1].set_title("Bending Moment")
-        axs[2].plot(points, slope(points))
-        axs[2].set_title("Slope")
-        axs[3].plot(points, deflection(points))
-        axs[3].set_title("Deflection")
-
-        fig.tight_layout()    # For better spacing between subplots
-        return axs
 
 
 class Beam_3d(Beam):


Test patch:
diff --git a/sympy/core/tests/test_evalf.py b/sympy/core/tests/test_evalf.py
index 27daed9015..1945945705 100644
--- a/sympy/core/tests/test_evalf.py
+++ b/sympy/core/tests/test_evalf.py
@@ -333,6 +333,8 @@ def test_implemented_function_evalf():
     assert str(f(2)) == "f(2)"
     assert f(2).evalf() == 3
     assert f(x).evalf() == f(x)
+    f = implemented_function(Function('sin'), lambda x: x + 1)
+    assert f(2).evalf() != sin(2)
     del f._imp_     # XXX: due to caching _imp_ would influence all other tests
 
 
diff --git a/sympy/core/tests/test_function.py b/sympy/core/tests/test_function.py
index d77f116137..f8ee69aab8 100644
--- a/sympy/core/tests/test_function.py
+++ b/sympy/core/tests/test_function.py
@@ -959,3 +959,13 @@ def test_function_assumptions():
     # way UndefinedFunction.__new__ works.
     f_real2 = Function('f', is_real=True)
     assert f_real2(x).is_real is True
+
+
+def test_undef_fcn_float_issue_6938():
+    f = Function('ceil')
+    assert not f(0.3).is_number
+    f = Function('sin')
+    assert not f(0.3).is_number
+    assert not f(pi).evalf().is_number
+    x = Symbol('x')
+    assert not f(x).evalf(subs={x:1.2}).is_number