Python numpy easier syntax? - python

I am new to numpy, and I'm already a little sick of its syntax.
Something which could be written like this in Octave/matlab
1/(2*m) * (X * theta - y)' * (X*theta -y)
Becomes this in numpy
np.true_divide(((X.dot(theta)-y).transpose()).dot((X.dot(theta)-y)),2*m)
This is much harder for me to write and debug. Is there any better way to write matrix operations like above so as to make life easier?

You can make some simplifications. By using from __future__ import division at the beginning of your program, all division will automatically be "true" division, so you won't need to use true_divide. (In Python 3 you don't even need to do this, since true division is automatically the default.) Also, you can use .T instead of .transpose(). Your code then becomes
1/(2*m) * ((X.dot(theta) - y).T).dot((X.dot(theta) - y))
which is a bit better.
In Python 3.5, a new matrix multiplication operator # is being added for basically this exact reason. This is not out yet, but when it is (and when numpy is updated to make use of it), your code will become very similar to the Octave version:
1/(2*m) * (X#theta - y).T # (X#theta - y)

You could try using np.matrix instead of np.ndarray for 2-dimensional arrays. It overloads the * operator so that it means matrix multiplication, so you can do away with all the .dots. Here are the docs.

There is a better way, but you will have to consult the numpy documentation to find it.
This page lists a bunch of equivalencies between matlab and numpy with simpler syntax. For example, a.transpose() can be written as a.T.
You can also look at the individual documentation for these functions, such as the one for true_divide which explains that the Python 3 / method works to do the same.

Related

Solving a complicated multivariable function with Python

I have a very complicated function of two variables, let's call them x and y. I want to create a Python program where the user can input two values, a and b, where a is the value of that complicated function of x and y, and b = math.atan(y/x). This program should then output the values of x and y.
I am clueless as to where to start. I have tried to make the function into that of just one variable, then generate many random values for x and pick the closest one, but I have learnt that this is horribly inefficient and produces a result which is only accurate to about 2 significant figures, which is pretty horrible. Is there a better way to do this? Many thanks!
(P.S. I did not reveal the function here due to copyright issues. For the sake of example, you can consider the function
a = 4*math.atan(math.sqrt(math.tan(x)*math.tan(y)/math.tan(x+y)))
where y = x * math.tan(b).)
Edit: After using the approach of the sympy library, it appears as though the program ignores my second equation (the complicated one). I suspect it is too complicated for sympy to handle. Thus, I am asking for another approach which does not utilise sympy.
You could use sympy and import the trigonometric functions from sympy.
from sympy.core.symbol import symbols
from sympy.solvers.solveset import nonlinsolve
from sympy import sqrt, tan, atan
y = symbols('y', real=True)
a,b = 4,5 # user-given values
eq2 = a - 4*atan(sqrt(tan(y/tan(b))*tan(y)/tan((y/tan(b))+y)))
S = nonlinsolve( [eq2], [y] )
print(S)
It'll return you a series of conditions ( ConditionSet object ) for possible adequate results.
If that wasn't clear enough, you can read the docs for nonlinsolve.

How to overload numeric operators in Python

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++ :)

ValueError: Math domain error (for a 2nd grade equation function)

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.)

Python and Numba for vectorized functions

Good day, I'm writing a Python module for some numeric work. Since there's a lot of stuff going on, I've been spending the last few days optimizing code to improve calculations times.
However, I have a question concerning Numba.
Basically, I have a class with some fields which are numpy arrays, which I initialize in the following way:
def init(self):
a = numpy.arange(0, self.max_i, 1)
self.vibr_energy = self.calculate_vibr_energy(a)
def calculate_vibr_energy(i):
return numpy.exp(-self.harmonic * i - self.anharmonic * (i ** 2))
So, the code is vectorized, and using Numba's JIT results in some improvement. However, sometimes I need to access the calculate_vibr_energy function from outside the class, and pass a single integer instead of an array in place of i.
As far as I understand, if I use Numba's JIT on the calculate_vibr_energy, it will have to always take an array as an argument.
So, which of the following options is better:
1) Create a new function calculate_vibr_energy_single(i), which will only take a single integer number, and use Numba on it too
2) Replace all usages of the function that are similar to this one:
myclass.calculate_vibr_energy(1)
with this:
tmp = np.array([1])
myclass.calculate_vibr_energy(tmp)[0]
Or are there other, more efficient (or at least, more Python-ic) ways of doing that?
I have only played a little with numba yet so I may be mistaken, but as far as I've understood it, using the "autojit" decorator should give functions that can take arguments of any type.
See e.g. http://numba.pydata.org/numba-doc/dev/pythonstuff.html

Python: efficiently generating a vector with different values

I'm programming a scientific application in Python, and the performance of my algorithm so far is terrible. I'm trying to find an efficient way to code what I'm doing. Basically, I have to multiply
def get_thing(self, chi, n):
return np.sum(self.an[n][j] * pow(chi, -j) for j in xrange(1, self.j))
where self.an[i][j] is a previously generated array. Then I'll have to do this:
pot = np.sum(self.coeffs[n] * self.get_thing(chi, n) for n in xrange(0, self.n))
where chi changes and cannot be cached, as it's a point that is being generated outside this class. Of course, this is extremely slow and not very bright. How can I improve this?
Thanks!
Within get_things you could certainly simplify things as something like:
def get_thing(self, chi, n):
return np.sum(self.an[n,1:self.j] * np.power(chi,-np.arange(1,self.j)))
Note, that you don't want to index numpy arrays using [i][j] notation; instead use [i,j].
You may be able to make further improvements using higher level broadcasting as #eat suggested.
Edit:
Made a couple of changes to the above code to try to get the indexing to match the OP and changed a sign error in my code.
Simply, try to do the computations in higher level of abstraction, i.e. try to avoid python level looping.
Study carefully how to do element-wise operations and how broadcasting operates, and last but not least don't forget the power of linear algebra!

Categories

Resources