Reputation: 151
I am trying to calculate below summation
where f_j,f_j
are functions of q calculated before and q=sin(theta)
where theta varies[0,90]
, and r_ij
is the respective distance bewteen each two elements I am doing this calculation for.
I used the sum()
function at first but it didn't work proberly as it returns a float number, but as q is changing and there's no summation for it I'm expecting an array!Ergo I gave it up.
My second approach was recursive function for calculating this summation,but I get so many errors and have no idea what is wrong with my code as I thing all the syntaxes are correct and I have no idea why I get errors or wrong values one after another!
theta=arange(radians(0.5), radians(40.010), radians(0.03))
q=sin(theta)
f_q_1= 2*exp(-3*pow(q,2))+4*exp(-5*pow(q,2))+1.95
f_q_2=...
.
f_q_i(or j).
atom_positions= open('coordinates.txt','r')
lines = atom_positions.readlines()
for i in range(0, len(lines)):
line = lines[i]
values = line.split(" ")
for j in range(0,len(lines)):
if j<>i:
nextLine = lines[j]
nextLineValues = nextLine.split(" ")
r =sqrt((float(values[5])-float(nextLineValues[5]))**2 + (float(values[6])
-float(nextLineValues[6]))**2+(float(values[7])-float(nextLineValues[7]))**2)
line_len = len(lines)
def I_tot(line_len,i,f_i,f_j,r):
I=0
if i<line_len:
I=I+(f_i*f_j*sin(q*r)/(q*r))
return I + I_tot(line_len,i,f_i,f_j,r)
else:
return I
else:
plot(2*theta,I_tot)
show()
atom_positions.close()
error:
RuntimeError: maximum recursion depth exceeded while calling a Python object
+This question is not a duplicate of recursive summation questions asked here before, As I checked them and couldn't find a solution to my problem.
I have also tried the function
def I_tot():
I=0
for i in range(0,len(lines)):
I=I+(f_i*f_j*sin(q*r)/(q*r))
return I
But I have no idea whether it gives me the correct summation or not, because the graph I get in the end is far from my expectation and indicates that this summation should not be correct.
Upvotes: 0
Views: 2921
Reputation: 486
Recursion in Python is limited. I would try summation anyway.
Note that in Numpy's sum function, you have two parameters:
def sum(a, axis=None, dtype=None, out=None, keepdims=False):
"""
Sum of array elements over a given axis.
Parameters
----------
a : array_like
Elements to sum.
axis : None or int or tuple of ints, optional
Axis or axes along which a sum is performed.
The default (`axis` = `None`) is perform a sum over all
the dimensions of the input array. `axis` may be negative, in
which case it counts from the last to the first axis.
...
The axis parameters tell it to sum in only sum of the dimensions. Meaning, if you sum along the q
and j
axis, you can still have a vector result in the q
axis .
You should have something similar to that.
import numpy as np
qs = np.array([1,2,3]) #Generate sum qs.
r = np.array([[11,21, 41,51]]) #the r_ij compnent. as a 1D vector
#(you can get it using reshape() )
np.kron(qs,r.T).sum(axis=0) #a vector containing sum(q*r) for each q.
Here, np.krons gives you
array([[ 11, 22, 33],
[ 21, 42, 63],
[ 41, 82, 123],
[ 51, 102, 153]])
and the summation gives
array([124, 248, 372])
A single element for each line.
You can easily generalize it to include f_i(q)
(a 2D array of the same structure), add sin
, etc.
Upvotes: 1
Reputation: 13539
still not sure what your end result is gonna be. But here are some starting points.
Use this to load inn the positions, calculate the distances and put it in a array.
import numpy as np
from scipy.spatial import distance
values = np.genfromtxt('coordinates.txt', dtype=float, usecols=[5,6,7])
r_ij = distance.squareform(distance.pdist(xyz))
nPositions = r_ij.shape()[0]
If you can make arrays of f_j
and f_i
, you can probably vectorize the summation, by utilizing array multiplication and the numpy version of sum. which allows you to define what axis to sum over.
Upvotes: 1