I was recently working with Python and wanted to use another way of finding square roots. For example I wanted to find square root of n with Newton-Raphson approximation. I need to overload the overload the ** (only when you raise a number to 0.5),o perator as well as math.sqrt(), because I have several older projects that could be sped up by doing so and replacing all math.sqrt() and **(0.5) with another function isn't ideal.
Could this be done in Python?
Is it possible to overload either ** or math.sqrt?
Any helpful links are also much appreciated.
def Square_root(n):
r = n/2
while(abs(r-(n/r)) > t):
r = 0.5 * (r + (n/r))
return r
print(2**(0.5)) ## changes to print(Square_root(2))
print(math.sqrt(2)) ## that also becomes print(Square_root(2))
In short: you can't change the behavior of __pow__ for built-in types.
Long answer: you can subclass the float, but it will require additional coding and refactoring of the input values of the program, to the new float class with overwritten operators and functions.
And you can overwrite the math.sqrt, but this is not recommended:
import math
math.sqrt = lambda x, y: print(x, y)
math.sqrt(3, 2)
# 3 2
This will require the custom function to have the same signature.
If you really want to overload languages int and float objects - you can use variants of magic functions. In order to be consistent, you'll have to write a lot of code.
A lot of work. Python is for lazy people - if you like to write a lot, stick to Java or C++ :)
Related
To keep things simplistic, consider the Python function:
def to_string(value):
return str(value)
Since we cannot define data types of parameters in Python (as for as I know), when I pass 1/2 to above function, it automatically converts 1/2 to 0.5 and then returns string '0.5'. How do I make it return '1/2'? How do I force Python to treat arguments to be of certain data type, no matter how they "appear"?
Here (in python 3) 1/2 is evaluated to 0.5 before being even passed into the function. For this specific example you have lost the information, due to possible float accuracy errors, before the function is even called; In theory you can get back to 1/2 from 0.5 but you should not rely on this float manipulation. In order to not lose this accuracy here you should probably treat a fraction as two pieces of integer information as it really is, instead of one float.
from fractions import gcd
def to_string(n, d):
g = gcd(n, d)
return str(n//g) + "/" + str(d//g)
If what you are asking is specifically about fractions then a class built around this idea is probably your best bet. If your example is not explanatory then (famously) python does not have type enforcement. However you can read here https://docs.python.org/3/library/typing.html about modernisation of this idea and decorators.
I decided to port some of my Python functions to C, mostly following this simple tutorial. Problem is that my C function returns a complex float, and there's no corresponding type in ctypes's documentation. This is is a problem I couldn't solve myself with my limited knowledge on cross-language coding and C, even extended by Google.
My C function works like this:
#include <tgmath.h>
float _Complex integrand(float _Complex theta1, double r, double z){
//[code] }
So, based on the tutorial, the corresponding Python wrapper (probably) should be something like this:
complextype = '??????'
_integr = ctypes.CDLL('libintegrand.so')
_integr.integrand.argtypes = (complextype, ctypes.c_double, ctypes.c_double)
def integrand(theta1, r, z):
global _integr
result = _integr.integrand(complextype(theta1), ctypes.c_double(r), ctypes.c_double(z))
return float(result)
But what should this type be? How should I do this?
If the fact that the function also has a complex argument makes it significantly more complicated, please ignore the complex argument.
Create a small C wrapper function:
void integrand_wrapper(float *re, float *im, double r, double z)
{
float _Complex result;
float _Complex theta = (*re) + I*(*im);
result = integrand(theta, r, z);
(*re) = creal(result);
(*im) = cimag(result);
}
The re and im pointers hold the real and imaginary parts of theta when called, and the real and imaginary parts of the result afterwards.
In your Python code, call integrand_wrapper() using e.g.
def integrand(theta, r, z):
global _integr
theta = complex(theta)
re = c_float(theta.real)
im = c_float(theta.imag)
_integr.integrand_wrapper(byref(re), byref(im), c_double(r), c_double(z))
return complex(float(re), float(im))
Note that if integrand() is defined in a binary library you cannot modify, you can always create another dynamic library containing only integrand_wrapper, that is dynamically linked (in C) to the original binary library.
Overall, I don't think the added overhead is significant at all. It is certainly worth testing.
Naively, perhaps split it into two arguments, Re(z), Im(z)
If that's not an option, perhaps pass the argument to the python function complex().
These are naive solutions; perhaps they don't work but if you haven't considered it and in lack of better responses, may be worth experimenting with.
Good luck!
I am wondering if there is an easy way to implement abstract mathematical Operators in Sympy. With operators I simply mean some objects that have 3 values as an input or 3 indices, something like "Operator(a,b,c)". Please note that I am refering to a mathematical operator (over a hilbert space) and not an operator in the context of programming. Depending on these values I want to teach Sympy how to multiply two Operators of this kind and how to multiply it with a float and so on. At some point of the calculation I want to replace these Operators with some others...
So far I couldn't figure out if sympy provides such an abstract calculation. Therefore I started to write a new Python-class for these objects, but this went beyond the scope of my limited knowledge in Python very fast... Is there a more easy way to implement that then creating a new class?
You may also want to look at SageMath, in addition to SymPy, since Sage goes to great lengths to come with prebuilt mathematical structures. However, it's been development more with eyes towards algebraic geometry, various areas of algebra, and combinatorics. I'm not sure to what extent it implements any operator algebra.
Yes, you can do this. Just create a subclass of sympy.Function. You can specify the number of arguments with nargs
class Operator(Function):
nargs = 3
If you want the function to evaluate for certain arguments, define the class function eval. It should return None for when it should remain unevaluated. For instance, to evaluate to 0 when all three arguments are 0, you might use
class Operator(Function):
#classmethod
def eval(cls, a, b, c):
if a == b == c == 0:
return Integer(0)
(note that nargs is not required if you define eval).
I've tried to solve the problem myself but i cant. Its a function in order to solve 2nd grade equations when y=0 like 'ax2+bx+c=0'. when i execute it it says me there is math domain error. if u can help me it will be nice thx.
a=raw_input('put a number for variable a:')
b=raw_input('put a number for variable b:')
c=raw_input('put a number for variable c:')
a=float(a)
b=float(b)
c=float(c)`
import math
x=(-b+math.sqrt((b**2)-4*a*c))/2*a
print x`
x=(-b-math.sqrt((b**2)-4*a*c))/2*a`
print x
PD:im starting with python so im quite a disaster sorry.
The issue here is that the standard math library in python cannot handle complex variables. The sqrt you've got up there reflects this.
If you want to handle a function that could have complex variables (such as the one above) I would suggest using the cmath library, which has a replacement cmath.sqrt function.
You could change your above code to the following:
from cmath import sqrt
a = raw_input('put a number for variable a:')
b = raw_input('put a number for variable b:')
c = raw_input('put a number for variable c:')
a = float(a)
b = float(b)
c = float(c)`
x = (-b + sqrt((b**2) - 4 * a * c)) / 2 * a
print x`
x = (-b - sqrt((b**2) - 4 * a * c)) / 2 * a`
print x
and it should fix your problem (I also made some edits to make the code look a little more pythonic (read: pep8 compliant))
First, it's worth noting that in "2nd grade math", that equation doesn't have a solution with the values you (presumably) entered.* When you get to high school math and learn about imaginary numbers, you learn that all quadratic equations actually do have solutions, it's just that sometimes the solutions are complex numbers. And then, when you get to university, you learn that whether or not the equations have solutions depends on the domain; the function to real numbers and the function to complex numbers are different functions. So, from either a 2nd-grade perspective or a university perspective, Python is doing the right thing by raising a "math domain error".
* Actually, do you even learn about quadratic equations before middle school? That seems a bit early…
The math docs explain:
These functions cannot be used with complex numbers; use the functions of the same name from the cmath module if you require support for complex numbers. The distinction between functions which support complex numbers and those which don’t is made since most users do not want to learn quite as much mathematics as required to understand complex numbers. Receiving an exception instead of a complex result allows earlier detection of the unexpected complex number used as a parameter, so that the programmer can determine how and why it was generated in the first place.
But there's another reason for this: math was specifically designed to be thin wrappers around the standard C library math functions. It's part of the intended goal that you can take code written for another language that uses C's <math.h>, C++'s <cmath>, or similar functions in Perl, PHP, etc. and have it work the same way with the math module in Python.
So, if you want the complex roots, all you have to do is import cmath and use cmath.sqrt instead of math.sqrt.
As a side note: In general, the operators and other builtins are more "friendly" than the functions from these modules. However, until 3.0, the ** operator breaks this rule, so ** .5 will just raise ValueError: negative number cannot be raised to a fractional power. If you upgrade to 3.x, it will work as desired. (This change is exactly like the one with integer division giving a floating-point result, but there's no __future__ statement to enable it in 2.6-2.7 because it was deemed to be less of a visible and important change.)
Does the Python language have a built-in function for an analog of map that sends an argument to a sequence of functions, rather than a function to a sequence of arguments?
Plain map would have "type" (thinking like Haskell) (a -> b) -> [a] -> [b]; is there anything with the corresponding type a -> [(a -> b)] -> [b]?
I could implement this in a number of ways. Here's using a lambda
def rev_map(x, seq):
evaluate_yourself_at_x = lambda f: f(x)
return map(evaluate_yourself_at_x, seq)
rev_map([1,2], [sum, len, type])
which prints [3, 2, list].
I'm just curious if this concept of "induce a function to evaluate itself at me" has a built-in or commonly used form.
One motivation for me is thinking about dual spaces in functional analysis, where a space of elements which used to be conceived of as arguments passed to functions is suddenly conceived of as a space of elements which are functions whose operation is to induce another function to be evaluated at them.
You could think of a function like sin as being an infinite map from numbers to numbers, you give sin a number, sin gives you some associated number back, like sin(3) or something.
But then you could also think of the number 3 as an infinite map from functions to numbers, you give 3 a function f and 3 gives you some associated number, namely f(3).
I'm finding cases where I'd like some efficient syntax to suddenly view "arguments" or "elements" as "function-call-inducers" but most things, e.g. my lambda approach above, seem clunky.
Another thought I had was to write wrapper classes for the "elements" where this occurs. Something like:
from __future__ import print_function
class MyFloat(float):
def __call__(self, f):
return f(self)
m = MyFloat(3)
n = MyFloat(2)
MyFloat(m + n)(type)
MyFloat(m + n)(print)
which will print __main__.MyFloat and 5.0.
But this requires a lot of overhead to redefine data model operators and so on, and clearly it's not a good idea to push around your own version of very basic things like float which will be ubiquitous in most programs. It's also easy to get it wrong, like from my example above, doing this:
# Will result in a recursion error.
MyFloat(3)(MyFloat(4))
There is no built-in function for that. Simply because that's definitely not a commonly used concept. Plus Python is not designed to solve mathematical problems.
As for the implementation here's the shortest one you can get IMHO:
rev_map = lambda x, seq: [f(x) for f in seq]
Note that the list comprehension is so short and easy that wrapping it with a function seems to be unnecessary in the first place.