Coding a recursive function - python

I need to create a sequence of number a_t according to a old sequence of number z_t and a_0. a_t is define equal to 27 if t=0 or a(t-1)exp(z(t-1)) for t>=1. I am not even sure how to write this is python. Here is a try
i=0
a_t=[]
a_0=27
z_t = pred_values
for x in pred_values:
a_t.append(a_0*exp(x))
i+=1
Is that a proper way to code that recursive function?
Update 1
I messed up in the code. Once we use a_0, we need to use a_t. For instance, if I want to use a_2, then clearly we will need to use a_1. Is there a proper way to code that function?
Update 2
It seems possible to work with a_0 only and the sum over z_t-1, z_t-2, ..., z0 instead of waiting for a_t-1 to compute a_t. So it is possible to vectorize the computation instead of computing the a_i one after the other. Are you up to give me the following option with numpy, i.e. a_t = a_0 exp(sum(z_i)) for i=0 to t-1? It is probably faster to compute as we already know the sequence z_t.

A straightforward way to define such a sequence is with a generator.
import math
def a_t(zs, a=27):
z = next(zs)
yield a
for z in zs:
a *= math.exp(z)
yield a
a_t = list(a_t(pred_values))

Related

Writing a function to compute a quantity in python based on a math problem

Write a function to compute the quantity
F(n) = n^2 Σ i=1 (i^3)
Read the problem as n squared over Sigma, with i = 1 under the sigma and I cubed at the end of the function.
I am not sure how to approach this idea. I tried setting up a function but I do not know how to use a function in Python to compute the problem we were given.
As mentioned above, I am sorry, but I do not know how to approach this problem.
I suppose the expected output here would be some quantity but because I haven't been able to make much progress, I have no clue what to expect exactly. To give more background, I understand how functions work but do not know how to approach this type of problem. Any help/guidance in writing this code would be greatly appreciated.
With a list comprehension:
Use the built-in functions, sum and range
def my_sigma(n_start: int, n_end: int) -> int:
return sum([i**3 for i in range(n_start, (n_end**2) + 1)])
# usage
print(my_sigma(1, 3))
>>> 2025
You can use the Math library to take the powers, and use a for loop for the sigma.
I think this would give you an idea,
for i in range (a , int(math.pow(n, 2))):
list_1.append(int(math.pow(i, 3)))
You can just put this inside a function with two variables a and n a representing the i in the sigma and n representing the n in the sigma.
You can use the sum function for summing up all the elements in the list if that is what you want.

Logarithm over x

Since the following expansion for the logarithm holds:
log(1-x)=-x-x^2/2-x^3/3-...
one can calculate the following functions which have removable singularities at x:
log(1-x)/x=-1-x/2-...
(log(1-x)/x+1)/x=-1/2-x/3-...
((log(1-x)/x+1)/x+1/2)/x=-1/3-x/4-...
I am trying to use NumPy for these calculations, and specifically the log1p function, which is accurate near x=0. However, convergence for the aforementioned functions is still problematic.
Do you have any ideas for any existing functions implementing these formulas or should I write one myself using the previous expansions, which will not be as efficient, however?
The simplest thing to do is something like
In [17]: def logf(x, eps=1e-6):
...: if abs(x) < eps:
...: return -0.5 - x/3.
...: else:
...: return (1. + log1p(-x)/x)/x
and play a bit with the threshold eps.
If you want a numpy-like, vectorized solution, replace an if with a np.where
>>> np.where(x > eps, 1. + log1p(-x)/x) / x, -0.5 - x/3.)
Why not successively take the Square of the candidate, after initially extracting the exponent component? When the square results in a number greater than 2, divide by two, and set the bit in the mantissa of your result that corresponds to the iteration. This is a much quicker and simpler way of determining log base 2, which can then in a single multiplication, be transformed to the e or 10 base.
Some predefined functions don't work at singularity points. One simple-minded solution is to compute the series by adding terms from a peculiar sequence.
For your example, the sequence would be :
sum = 0
for i in range(n):
sum+= x^k/k
sum = -sum
for log(1-x)
Then you keep adding a lot of terms or until the last term is under a small threshold.

Avoiding hard coding a lot of coupled ODEs in python

First of, I'm sorry if the title is not entirely fitting, I had a hard time finding an appropriate one (which might have also effect my searching efficiency for already asked questions like this :/ ).
The problem is the following. While it is comparably easy to solve coupled ODE's in python with Scipy, I still have to write down my ODE in the form explicitly. For example for a coupled ODE of the form
d/dt(c_0)=a(c_0)+b(c_1) and d/dt(c_1)=c(c_0)
I would set up sth like:
import numpy as np
from scipy.integrate import ode
a=1
b=2
c=3
val=[]
def dC_dt(t, C):
return [a*C[0]+b*C[1],
c*C[0]]
c0, t0 = [1.0,0.0], 0
r = ode(dC_dt).set_integrator('zvode', method='bdf',with_jacobian=False)
r.set_initial_value(c0, t0)
t1 = 0.001
dt = 0.000005
while r.successful() and r.t < t1:
r.integrate(r.t+dt)
val.append(r.y)
However, now I have coupled ODE's of the rough form
d/dt(c_{m,n})=a(c_{m,n})+b(c_{m+1,n-1})+k(c_{m-1,n+1})
with c_{0,0}=1 and I have to include orders with m^2+n^2-mn smaller than a max value.
For a small max, what I did, is using a dictionary to use a notation with two indices and map it on a 1D list
dict_in={'0,0':0,'-1,0':2,...}
and then I entered the ODE for each order
def dC_dt(t,C):
return[a*C[dict_in['0,0']]+b*C[dict_in['1,-1']]...
Now I basically have to do that for some 100 coupled equations, which I ofc do not want to hard code, so I was trying to figure out a way, to realize the ODE's with a loop or sth. However I couldn't yet find a way around the fact of having two indices in my coefficients together with the condition of only including orders with m^2+n^2-mn smaller than a max value.
As I am running in some deadlines, I figured it is time to ask smarter people for help.
Thanks for reading my question!
I had a similar problem. If you fill you dictionary you can just redeclare the function more times inside the loop. This is a silly example of how it works:
dict_in={'0,0':0,'-1,0':2}
for elem in dict_in:
def dC_dt(t,C):
#return[a*C[dict_in['0,0']]+b*C[dict_in['1,-1']]
return dict_in[elem]
t, C = 0, 0
print(dC_dt(t,C))
#r = ode(dC_dt).set_integrator('zvode', method='bdf',with_jacobian=False)
If you need to use more functions together you can use anonymous functions and store them in memory. Another example:
functions_list = list()
for i in range(4):
f = lambda n = i: n
functions_list.append(f)
for j in range(4):
print(functions_list[j]())
You can use a list or a generator too. For example you can write down the value on a txt file and read that with the readline function each time.
As pointed in the comments below, if you use lamda functions you should pay attention to references. See also https://docs.python.org/3/faq/programming.html#why-do-lambdas-defined-in-a-loop-with-different-values-all-return-the-same-result

A 'simple' boundary value/ initial value p‌r‌o‌b‌l‌e‌m in numpy

tl/dr: I have a numpy boundary/initial value problem and want to see if I'm approaching this the right way. I'm fairly new with numpy. I'm presenting a simplified version of the problem.
I have 2 functions a and b defined for integer values of t and x, which I'm trying to calculate for positive x and t (say up to N ). I want to figure out the best way to do this with numpy.
I have boundary values at t=0 and x=0, a(t,x) depends only on a(t-1,x-1) and b(t-1,x-1) while b(t,x) depends on lots of values of a with smaller t, x . This is what makes it 'simple'. We have
a=1 for t=0 and for x=0.
b=0.1 for for t=0 and b=1 for x=0. At x=t=0, we get b=0.1.
In the interior, a(t,x) = a(t-1,x-1) - b(t-1,x-1).
Now the hard part. b(t,x) = a(t-1,x-1) S(t, t-1) + a(t-2,x-2) S(t,t-2) + ...
where S(t,y) is a sum equal to f(a(t-1,1)) + f(a(t-1,2)) + ... + f(a(t-1,y)) for some function f (If you need something specific, you could assume it's just a + a**2).
So my plan is to do this basically as:
initialize values
loop over t:
update a
loop over y:
define the S(t,y) #each step is vectorizable I think
loop over x:
set b to equal the dot product between vector of S and slice of a.
My question: Is this a reasonable approach - can I cut out any of those loops, or should I take a different tack entirely?
Bonus question: Any likely errors for a numpy newb to make coding this?

Sum of Square Differences (SSD) in numpy/scipy

I'm trying to use Python and Numpy/Scipy to implement an image processing algorithm. The profiler tells me a lot of time is being spent in the following function (called often), which tells me the sum of square differences between two images
def ssd(A,B):
s = 0
for i in range(3):
s += sum(pow(A[:,:,i] - B[:,:,i],2))
return s
How can I speed this up? Thanks.
Just
s = numpy.sum((A[:,:,0:3]-B[:,:,0:3])**2)
(which I expect is likely just sum((A-B)**2) if the shape is always (,,3))
You can also use the sum method: ((A-B)**2).sum()
Right?
Just to mention that one can also use np.dot:
def ssd(A,B):
dif = A.ravel() - B.ravel()
return np.dot( dif, dif )
This might be a bit faster and possibly more accurate than alternatives using np.sum and **2, but doesn't work if you want to compute ssd along a specified axis. In that case, there might be a magical subscript formula using np.einsum.
I am confused why you are taking i in range(3). Is that supposed to be the whole array, or just part?
Overall, you can replace most of this with operations defined in numpy:
def ssd(A,B):
squares = (A[:,:,:3] - B[:,:,:3]) ** 2
return numpy.sum(squares)
This way you can do one operation instead of three and using numpy.sum may be able to optimize the addition better than the builtin sum.
Further to Ritsaert Hornstra's answer that got 2 negative marks (admittedly I didn't see it in it's original form...)
This is actually true.
For a large number of iterations it can often take twice as long to use the '**' operator or the pow(x,y) method as to just manually multiply the pairs together. If necessary use the math.fabs() method if it's throwing out NaN's (which it sometimes does especially when using int16s etc.), and it still only takes approximately half the time of the two functions given.
Not that important to the original question I know, but definitely worth knowing.
I do not know if the pow() function with power 2 will be fast. Try:
def ssd(A,B):
s = 0
for i in range(3):
s += sum((A[:,:,i] - B[:,:,i])*(A[:,:,i] - B[:,:,I]))
return s
You can try this one:
dist_sq = np.sum((A[:, np.newaxis, :] - B[np.newaxis, :, :]) ** 2, axis=-1)
More details can be found here (the 'k-Nearest Neighbors' example):
https://jakevdp.github.io/PythonDataScienceHandbook/02.08-sorting.html
In Ruby language you can achieve this in this way
def diff_btw_sum_of_squars_and_squar_of_sum(from=1,to=100) # use default values from 1..100.
((1..100).inject(:+)**2) -(1..100).map {|num| num ** 2}.inject(:+)
end
diff_btw_sum_of_squars_and_squar_of_sum #call for above method

Categories