For some bizarre reason, I am struggling to get my head around iterators/generators as used in Python (I write/use them with no problem in C++ - but somehow I can't seem to grok how to write one using Python).
I have a mathematical function of the form:
f(a,b) = ( v1(a) - v1(b) ) / ( v2(a) - v2(b) )
Where v1 and v2 are equal length 1D vectors.
I want to write a function (actually, a generator), that generates the output of f() as defined above.
Can anyone help?
[[Edit]]
My notation may have been confusing. I hope to clarify that. The function described above return a set of values. With the argument b taking on values, in the interval (a,b]
So for example if we call f(1,5), the function will return the following values (not functions -in case my clarification below causes further confusion):
f(1,1)
f(1,2)
f(1,3)
f(1,4)
f(1,5)
You can use generator expression:
def f(a, b):
return ((v1[a] - v1[i]) / (v2[a] - v2[i]) for i in xrange(a, b+1))
Or a generator function
def f(a, b):
for i in xrange(a, b+1)
yield (v1[a] - v1[i]) / (v2[a] - v2[i])
The generator may look like that, since there is no iteration (as kindall correctly noted).
def f(a, b):
yield (v1[a] - v1[b]) / (v2[a] - v2[b]) # be careful about division!
Couple notes:
there is nothing to iterate through, and generators are generally used in iterations,
be careful about divisions: in Python 2.x a / b returns integer if both a and b are integers (so 4 / 3 == 1) - you can avoid this by using floats or by from __future__ import division,
Related
I'm writing code for the method to solve this cubic equation. I use python's math library.
(float)(-b+pow(pow(b,3)-27*pow(a,2)*d,1/3))/3*a;
(float)((math.sqrt(delta))/(3*a))*((pow(abs(k)+math.sqrt(pow(k,2)+1),1/3))+(pow(abs(k)-math.sqrt(pow(k,2)+1),1/3)))-(b/(3*a));
Below are pictures of 2 math formulas I need to solve:
A few comments to begin with:
/3*a at the end of your first line does not do what you think it does. Use parentheses!! Parentheses are important. Write / (3 * a) instead.
It's mostly a matter of style, but personally I think A**B is easier to read than pow(A, B) (they are equivalent, as you can see in the documentation).
Note that your code will require b, a, d, Delta and k to be already-existing variables with already-given values. One way to get around that is to encapsulate your code into a function, with these four variables as arguments of the function. Another way to get around that is to use the symbolic expression library sympy.
With these comments in mind, here are two ways to rewrite your first expression and use it in python code. I will let you adapt the second expression yourself.
First way: encapsulating in a function with arguments
def expr1(a,b,d):
numerator = - b + (b**3 - 27*a*a*d)**(1/3)
denominator = 3 * a
return numerator / denominator
print(expr1(2,7,3))
# -0.7219330585463425
Second way: using sympy
Sympy is a library for symbolic calculus. This means we can use it to define symbols, which are basically variables without a value, and then ask it to remember expressions that use these symbols. We are going to use the function sympy.symbols to define our symbols, and expr.subs to evaluate an expression expr by giving values to those symbols. I encourage you to read sympy's documentation.
import sympy
a, b, d = sympy.symbols('a b d')
numerator = - b + (b**3 - 27*a*a*d) ** (1/3)
denominator = 3 * a
expr1 = numerator / denominator
print(expr1)
# (-b + (-27*a**2*d + b**3)**0.333333333333333)/(3*a)
print(expr1.subs([(a,2), (b,7), (d,3)]))
# -0.721933058546343
I'm looking for an efficient way to compute the result of a (complex) mathematical function.
right now it looks comparable to:
def f(x):
return x**2
def g(x):
if not x: return 1
return f(x)*5
def h(x):
return g(x)
with concurrent.futures.ProcessPoolExecutor() as executor:
print(list(executor.map(h, params)))
since every function call is costly in Python, the code should already run faster if f(x) is merged with g(x). Unfortunately in that case the 'return ...' line of the g(x) function becomes very long already. Furthermore there are currently actually 6 functions defined in total, so the complete formula occupies several lines.
So, what's a clever way to compute the result of a physics formula?
EDIT:
Thank you so far, but my question is not really about this specific snippet of code but more about the way to implement physics formulas in Python. For example one could also define the expression as a string and evaluate it using eval() but that is obviously slower.
To be more specific I have a potential and want to implement it parallel. Therefore I call my version of "h(x)" using the map function of a ProcessPoolExecutor (with different values each time). But is it best practice to define the function as a function that calls other functions or uses variables? Is there a more efficient way?
def formula(x):
if not x :
return 1
return x*x*5
I don't think the line is in danger of being problematically long, but if you're concerned about the length of the return ... line you could use intermediate values, e.g.:
def g(x):
if x == 0:
return 1
x2 = x ** 2
return x2 * 5
As an aside, in this context it is incorrect to use the is operator as in x is 0. It does not check for numerical equality, which is what == does. The is operator checks that the two operands refer to exactly the same object in memory, which happens to have the same behaviour as == in this case because the Python interpreter is intelligently reusing number objects. It can lead to confusing errors, for example:
a = 1234
b = 1233
a == (b + 1) # True
a is (b + 1) # False
In practice, is is mainly used only to check if a value is None.
Give the Python function XOR(a,b) that returns the XOR(a,b) where a and b are integers. Submit a complete Python program that uses XOR in file xor.py
This is confusing to me, am I being asked to find integers for a and b
or is it saying a and b begin as integers? I'm generally very confused by
python so this probably seems like a simple question but I do not know where
to even begin with writing the code.
I know the outline of the code should be
def XOR(a,b):
# Your code here
nbr1 = 67
nbr2 = 73
print (XOR(nbr1, nbr2))
The ^ operator in Python is XOR, so you can just do:
def XOR(a,b):
return a ^ b
nbr1 = 67
nbr2 = 73
print (XOR(nbr1, nbr2))
The XOR is just a mathematical function like multiplication, subtraction, addition etc. You might be more familiar with to the power of then XOR. For example, 5 to the 2nd power is 5^2 or XOR(5,2). You just have to create a def called XOR which takes two arguments and returns one of them raised to the other. It's not specified which argument should be taken as the power so you can just take the 2nd one maybe. This is the code:
def XOR(num1,num2):
return num1^num2
print(XOR(5,2))
#prints 25
a and b are integers to begin with. XOR is shorthand for "Exclusive Or" or "Exclusive Disjunctive." Basically, this means a or b, but not a and b ( remember that OR can mean a or b or a and b). It sounds like you are being to write a function that when given two values returns one of the values. You might try this:
import random
XOR(a, b):
list = [a , b ]
return random.choice(list)
I am new to StackOverflow, and I am extremely new to Python.
My problem is this... I am needing to write a double-sum, as follows:
The motivation is that this is the angular correction to the gravitational potential used for the geoid.
I am having difficulty writing the sums. And please, before you say "Go to such-and-such a resource," or get impatient with me, this is the first time I have ever done coding/programming/whatever this is.
Is this a good place to use a "for" loop?
I have data for the two indices (n,m) and for the coefficients c_{nm} and s_{nm} in a .txt file. Each of those items is a column. When I say usecols, do I number them 0 through 3, or 1 through 4?
(the equation above)
\begin{equation}
V(r, \phi, \lambda) = \sum_{n=2}^{360}\left(\frac{a}{r}\right)^{n}\sum_{m=0}^{n}\left[c_{nm}*\cos{(m\lambda)} + s_{nm}*\sin{(m\lambda)}\right]*\sqrt{\frac{(n-m)!}{(n+m)!}(2n + 1)(2 - \delta_{m0})}P_{nm}(\sin{\lambda})
\end{equation}
(2) Yes, a "for" loop is fine. As #jpmc26 notes, a generator expression is a good alternative to a "for" loop. IMO, you'll want to use numpy if efficiency is important to you.
(3) As #askewchan notes, "usecols" refers to an argument of genfromtxt; as specified in that documentation, column indexes start at 0, so you'll want to use 0 to 3.
A naive implementation might be okay since the larger factorial is the denominator, but I wouldn't be surprised if you run into numerical issues. Here's something to get you started. Note that you'll need to define P() and a. I don't understand how "0 through 3" relates to c and s since their indexes range much further. I'm going to assume that each (and delta) has its own file of values.
import math
import numpy
c = numpy.getfromtxt("the_c_file.txt")
s = numpy.getfromtxt("the_s_file.txt")
delta = numpy.getfromtxt("the_delta_file.txt")
def V(r, phi, lam):
ret = 0
for n in xrange(2, 361):
for m in xrange(0, n + 1):
inner = c[n,m]*math.cos(m*lam) + s[n,m]*math.sin(m*lam)
inner *= math.sqrt(math.factorial(n-m)/math.factorial(n+m)*(2*n+1)*(2-delta[m,0]))
inner *= P(n, m, math.sin(lam))
ret += math.pow(a/r, n) * inner
return ret
Make sure to write unittests to check the math. Note that "lambda" is a reserved word.
I tried to work out a python-like language which combined with the feature of MACRO(weird, but just for fun..), for example, the codes to calculate fibonacci seq analyticly is like this:
from math import *
def analytic_fibonacci(n):
sqrt_5 = sqrt(5);
p = (1 + sqrt_5) / 2;
q = 1/p;
return int( (p**n + q**n) / sqrt_5 + 0.5 )
print analytic_fibonacci(10),
And I can rewrite it in the python-like-with-MACRO language like this:
from math import sqrt
sqrt
def analytic_fibonacci(n):
_2(5)
(1+_1)/2
1/_1
return int((_2**n+_1**n)/_3+0.5)
print analytic_fibonacci(10)
The idea is to use line number to expand the expression so that no explicit assignment is needed. The _2 means to replace it with the expression appeared 2 lines smaller than the current line, so the _2 in the 4th line becomes the expression in the 2nd line, which is sqrt, and _2(5) is expanded to sqrt(5). (Lines before current line starts with _, after current line starts with |)
The example above is simple. When I tried to rewrite a more complex example, I encountered problem:
def fibIter(n):
if n < 2:
return n
fibPrev = 1
fib = 1
for num in xrange(2, n):
fibPrev, fib = fib, fib + fibPrev
return fib
I don't know how to use the line-number-based MACRO to express fibPrev, fib = fib, fib + fibPrev. I think some features is missing in this "MACRO langugage" , and fibPrev, fib = fib, fib+fibPrev is expressible if I fixed it.. (I heard that the MACRO in Lisp is Turing Complete so I think the example above should be expressed by MACRO) Does anyone have ideas about this?
I see two ways to interpret your language. Neither is very powerful.
The first way is to literally expand the macros to expressions, rather than values. Then analytic_fibonacci expands to
def analytic_fibonacci(n):
return int(((1+sqrt(5))/2**n+1/(1+sqrt(5))/2**n)/sqrt(5)+0.5)
You probably want some parentheses in there; depending on how you define the language, those may or may not be added for you.
This is pretty useless. Multiple-evaluation problems abound (where a function is reexecuted every time a macro refers to it), and it only lets you do things you could have done with ordinary expressions.
The second interpretation is that every statement consisting of a Python expression implicitly assigns that expression to a variable. This is also pretty useless, because only one statement can assign to any of these implicit variables. There's no way to do
x = 0
for i in range(5):
x += i
because you can't have the equivalent of x refer to either _2 or _0 depending on where the last assignment came from. Also, this really isn't a macro system at all.
Using the second interpretation, we can add a new operator to bring back the power of ordinary variable assignments. We'll call this the merge operator.
merge(_1, _2)
evaluates to either _1 or _2, depending on which was evaluated most recently. If one of the arguments hasn't yet been evaluated, it defaults to the other. fibIter then becomes
def fibIter(n):
if n < 2:
return n
1 # fibPrev
1 # fib
for num in xrange(2, n):
merge(_2, _-1) # temp
merge(_4, _-1) + merge(_3, _0) # fib
_2 # fibPrev
return merge(_2, _5)
This is quite awkward; essentially, we have to replace every use of a variable like x by a merge of every location it could have been assigned. It also requires awkward line counting, making it hard to tell which "variable" is which, and it doesn't handle multiple assignments, for loop targets, etc. I had to use negative indices to refer to future lines, because we need some way to refer to things assigned later.
Lisp macros are more powerful than your language because they let you apply arbitrary Lisp code to your Lisp code. Your language only allows a macro to expand to fixed expressions. A Lisp macro can take arbitrary code as arguments, cut it up, rearrange it, replace parts of it with different things depending on conditionals, recurse, etc. Your macros can't even take arguments.