I have a simple for loop to calculate RMS(root mean square) which is defined in sigma summation form:
for i in range(int(N-(n*periyot/delta)), N+1):
sum = np.sqrt((1 / N) * (sum((Cl[i]**2))))
Then I got this error:
TypeError: 'numpy.float64' object is not iterable
Here are some information about my definitons:
N=40000, n=10.0, periyot=6.451290, delta=0.005
Cl=[-21.91969 -12.452671 -7.928303 ..., -0.0833991 -0.0579686
-0.0823822]
Remove that sum, each element of Cl is a float so you can't possibly call sum on them:
>>> sum(2.4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'float' object is not iterable
If you intend to invoke numpy's broadcasting to perform the power operation then you don't need to index the array.
The problem is that you overwrite sum function with sum variable. Try something like this:
my_sum = 0
for i in range(int(N-(n*periyot/delta)), N+1):
my_sum += np.sqrt((1 / N) * (sum((Cl[i]**2))))
Replicating your calculation, a bit simplified:
In [1]: Cl = np.array([-21.91969 , -12.452671 , -7.928303 , -0.0833991,-0.0579686,-0.0823822])
To calculate a sum in a loop, initial a value, and add to it at each iteration:
In [2]: res = 0
In [3]: for i in range(len(Cl)):
...: res += np.sqrt((1/3)*Cl[i]**2)
...:
In [4]: res
Out[4]: 24.551481812296061
Letting numpy calculate everything (slightly different)
In [5]: np.sqrt((1/3)*Cl**2).sum()
Out[5]: 24.551481812296064
Your range is a little more complicated, but I think that can be accommodated with:
s, e = int(N-(n*periyot/delta)), N+1 # start, end of range
for i in range(s, e): ....
or
np.sqrt((1/N) * Cl[s:e]**2).sum()
But I wonder why you started with that sum((Cl[i]**2))). Where you hoping to square a range of Cl values and then sum them? And repeat that for multiple ranges?
=============
There's a np.sum and a Python sum. Python sum works nicely with a list of numbers, such as those generated by a list comprehension:
In [6]: [np.sqrt((1/3)*Cl[i]**2) for i in range(len(Cl))]
Out[6]:
[12.655338922053147,
7.1895529539798462,
4.5774078712669173,
0.048150492835172518,
0.03346818681454574,
0.047563385346433583]
In [7]: sum([np.sqrt((1/3)*Cl[i]**2) for i in range(len(Cl))])
Out[7]: 24.551481812296061
The errors that result from trying to apply sum to a single value:
In [9]: sum(Cl[0])
....
TypeError: 'numpy.float64' object is not iterable
In [10]: sum(12.234)
...
TypeError: 'float' object is not iterable
In [11]: sum(Cl[:3]) # sum of several items
Out[11]: -42.300663999999998
==========
RMS = ( (1 / N ) * (Cl[1]^2 + Cl[2]^2 + Cl[3]^2 + ... Cl[N]^2) ) ^0.5
is expressed, for lists as:
rms = (1/n) * math.sqrt(sum([Cl[1]**2, Cl[2]**2, ....]))
rms = (1/n) * math.sqrt(sum([Cl[i]**2 for i in range(len(Cl))]))
rms = (1/n) * math.sqrt(sum([c**2 for c in Cl])) # iterate on Cl directly
rms = (1/n) * np.sqrt(np.sum(Cl**2)) # for array Cl
Related
I'm implementing this equation and using it for the set of frequencies nos:
The non vectorized code works:
import numpy as np
h = np.array([1,2,3])
nos = np.array([4, 5, 6, 7])
func = lambda h, no: np.sum([hk * np.exp(-1j * no * k) for k, hk in enumerate(h)])
# Not vectorized
resps = np.zeros(nos.shape[0], dtype='complex')
for i, no in enumerate(nos):
resps[i] = func(h, no)
print(resps)
> Out: array([-0.74378734-1.45446975j,
> -0.94989022+3.54991188j,
> 5.45190245+2.16854975j,
> 2.91801616-4.28579526j])
I'd like to vectorize the call in order to pass nos at once instead of explicitly iterating:
H = np.vectorize(func, excluded={'h'}, signature='(k),(n)->(n)')
resps = H(h, nos)
When calling H:
Error: ValueError: 0-dimensional argument does not have enough dimensions for all core dimensions ('n',)
I'm using the signature parameter but I'm not sure I use it in the correct way. Without this parameter there is an error in func:
TypeError: 'numpy.int32' object is not iterable
I don't understand where the problem is.
A list comprehension version of your loop:
In [15]: np.array([func(h,n) for n in nos])
Out[15]:
array([-0.74378734-1.45446975j, -0.94989022+3.54991188j,
5.45190245+2.16854975j, 2.91801616-4.28579526j])
vectorize - excluding the first argument (by position, not name), and scalar iteration on second.
In [16]: f=np.vectorize(func, excluded=[0])
In [17]: f(h,nos)
Out[17]:
array([-0.74378734-1.45446975j, -0.94989022+3.54991188j,
5.45190245+2.16854975j, 2.91801616-4.28579526j])
No need to use signature.
With true numpy vectorization (not the pseudo np.vectorize):
In [23]: np.sum(h * np.exp(-1j * nos[:,None] * np.arange(len(h))), axis=1)
Out[23]:
array([-0.74378734-1.45446975j, -0.94989022+3.54991188j,
5.45190245+2.16854975j, 2.91801616-4.28579526j])
Update:
I want to run a generate_function(3) for example to have an output of:
c_0 * F(0) + c_1 * F(1) + c_2 * F(2) + c_3 * F(3)
where c_i is just a symbol, while F(i) is a function or an object that I can use later for the rest of code.
I simply want to use SymPy to implement the summation:
summation (from i = 0 to n) c_i * f(i)
where c_i is indexed constant (symbol) and f is a function with argument of i.
I tried many times and failed.
def generate(n):
coeff = sym.symbols('c0:{}'.format(n))
def f(i):
return i
return sym.Sum(coeff(i) * f(i),(i,0,n))
I got: 'tuple' object is not callable
Thanks for help
It's not completely clear what you want but maybe this is it:
In [31]: C = IndexedBase('C')
In [32]: f = Function('f')
In [33]: i, n = symbols('i, n')
In [34]: s = Sum(C[i] * f(i), (i, 0, n))
In [35]: s
Out[35]:
n
___
╲
╲
╱ f(i)⋅C[i]
╱
‾‾‾
i = 0
You created a tuple of symbols:
In [8]: coeff = symbols("c0:{}".format(n))
In [9]: coeff
Out[9]: (c0a, c0b, c0c, c0d, c0e, c0f, c0g, c0h, c0i, c0j, c0k, c0l, c0m, c0n)
Treating such a tuple as though it were a function, as in f(i), does not work. That's basic Python! While the indexing is a nice short to making many symbols, the result is no different from doing symbols('x y z')
In [10]: coeff(0)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Input In [10], in <module>
----> 1 coeff(0)
TypeError: 'tuple' object is not callable
You can index the tuple
In [11]: coeff[0]
Out[11]: c0a
You could use a list comprehension to make a list of expressions:
In [14]: [coeff[i] * f(i) for i in range(5)]
Out[14]: [0, c0b, 2⋅c0c, 3⋅c0d, 4⋅c0e]
and even apply the base sum function to create a sympy.Add expression:
In [16]: sum([coeff[i] * f(i) for i in range(5)])
Out[16]: c0b + 2⋅c0c + 3⋅c0d + 4⋅c0e
This is a followup question from the one I posted a few minutes ago. The problem I was having with multiplying int with float is fixed, thanks to user2357112 in the comments. However, it's come across another roadblock.
Code:
from __future__ import division
from fractions import Fraction
import numpy as np
from numpy import linalg as LA
def gcd(m,n):
if m < n:
return gcd(n,m)
return gcd(n,m%n)
def lcm(m,n):
return (m*n)/(gcd(m,n))
def answer(m):
tbd = []
l = len(m)
for i in range(l):
s = sum(m[i])
if s == 0:
tbd.append(i)
m[i][i] = 1
else:
for j in range(l):
m[i][j] /= s
tbd.sort(reverse=True)
a = np.array(m)
r = np.diag([1.0 for x in range(l)])
for i in range(100):
r *= a
initial = [0 for x in range(l)]
initial[0] = 1
final = initial * r
for i in tbd:
del final[i]
dens = []
for i in range(len(final)):
final[i] = final[i].limit_denominator()
dens.append(final[i].denominator)
lc = dens[0]
for j in range(1,len(dens)):
lc = lcm(lc,dens[j])
for i in range(len(final)):
final[i] = int(final[i] * lc)
final.append(lc)
return final
def main():
print answer([[1,2],[2,1]])
print answer([[0,1,0,0,0,1],[4,0,0,3,2,0],[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0]])
main()
Code in ideone: http://ideone.com/DO1otS
Error:
Traceback (most recent call last):
File "prog.py", line 51, in <module>
File "prog.py", line 48, in main
File "prog.py", line 37, in answer
AttributeError: 'numpy.ndarray' object has no attribute 'limit_denominator'
I am confused about why final[i] was recognized as a numpy.ndarray object. I thought that, since final is a 1-dimensional array, final[i] will therefore return the value (a float) within that array at index i. I'm not sure why that is not the case. Thank you in advance!
This is the answer to your question "I am confused about why final[i] was recognized as a numpy.ndarray object." In the following snippet of code
r = np.diag([1.0 for x in range(l)])
initial = [0 for x in range(l)]
final = initial * r
I skipped non-essential code. The code above shows that r is a numpy.ndarray and initial is a list. Then final is a product of a numpy.ndarray and a list. The result of this product is a numpy.ndarray.
What is also important is that r is an array of floats. Therefore final is also an array of floats and not fraction objects. Therefore you cannot call limit_denominator() on elements of final.
In addition, code such as:
for i in tbd:
del final[i]
looks quite suspicious.
I am working on Google's "Doomsday Fuel" problem in Python 2.7 (it needs to be done in Python 2.7, hence the from __future__ import division line) that uses NumPy, which admittedly I am not too familiar with.
The WIP code (with a lot of comments added for your convenience):
from __future__ import division
from fractions import Fraction
import numpy as np
from numpy import linalg as LA
def gcd(m,n):
'''
function for finding the greatest common divisor of m and n
used mostly for the LCM function
'''
if m < n:
return gcd(n,m)
return gcd(n,m%n)
def lcm(m,n):
'''
function for finding the least common multiple of m and n
using the fact that m*n = gcd(m,n)*lcm(m,n)
'''
return (m*n)/(gcd(m,n))
def answer(m):
'''
m is an square matrix of nonnegative integers
dimensions guaranteed to be at most 10x10
'''
tbd = [] #stands for To Be Deleted
l = len(m)
for i in range(l):
'''
Checks each row
If row i is empty, add i to tbd, then make m[i][i] = 1
Otherwise, divide row i by the sum of row i to "normalize" it
e.g. [[3,2],[0,0]] would become [[0.6,0.4],[0,1]]
'''
s = sum(m[i])
if s == 0:
tbd.append(i)
m[i][i] = 1
else:
for j in range(l):
m[i][j] /= s
tbd.sort(reverse=True)
a = np.array(m)
r = np.diag([1 for x in range(l)]) #set initial matrix r which is just the identity matrix with same dimensions as a
for i in range(100):
r *= a #with each row adding up to just 1, r should stay stable
initial = [0 for x in range(l)]
initial[0] = 1
final = initial * r
for i in tbd:
del final[i]
dens = [] #denominators
for i in range(len(final)):
final[i] = final[i].limit_denominator()
dens.append(final[i].denominator) #collect all denominators
lc = dens[0]
for j in range(1,len(dens)):
lc = lcm(lc,dens[j]) #find LCM of all the denominators
for i in range(len(final)):
final[i] = int(final[i] * lc) #multiply the final array (which uses Fractions) by the LCM, then convert elements to int
final.append(lc)
return final
def main():
print answer([[1,2],[2,1]])
print answer([[0,1,0,0,0,1],[4,0,0,3,2,0],[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0]])
main()
Code in Ideone: http://ideone.com/DO1otS
The error message:
Traceback (most recent call last):
File "prog.py", line 51, in <module>
File "prog.py", line 48, in main
File "prog.py", line 29, in answer
TypeError: Cannot cast ufunc multiply output from dtype('float64') to dtype('int64') with casting rule 'same_kind'
Why can't the program multiply int and float together? Or is there another part in this error message that I'm missing?
I am having a problem with calling a function twice. If I comment my last 3 lines and keep show(), I don't get any errors and things come as they are suppose to. However, if I don't comment them out calling the last function again gives me this error:
Traceback (most recent call last):
File "second_1.py", line 29, in <module>
domega=c_d(len(t),t,z)
File "second_1.py", line 25, in c_d
dy[1:-1]=(y[2:]-y[0:-2])/(x[2:]-x[0:-2])
TypeError: unsupported operand type(s) for -: 'list' and 'list'
Here is the function:
import numpy as np
from pylab import *
import time
t_initial=time.time()
clf()
t,hp,hn= np.loadtxt("Richardson.dat", usecols=(0,1,2),comments='#', unpack=True) # to select just a few columns
print(time.time()-t_initial)
def phi(y,x):
return(np.arctan(y/x))
phase=[0.0]*len(t)
phase=phi(hp[0:],hn[0:])
#plot(t,phase)
#show()
def c_d(order,x,y):
dy=[0.0]*order
dy[0]=(y[1]-y[0])/(x[1]-x[0])
dy[-1]=(y[-1]-y[-2])/(x[-1]-x[-2])
dy[1:-1]=(y[2:]-y[0:-2])/(x[2:]-x[0:-2])
return(dy);
z=c_d(len(t),t,phase);
plot(t,z)
print(len(z)-len(t))
domega=c_d(len(t),t,z)
plot(t,domega)
show()
The problem is very clearly explained in the error message:
The '-' operand is not applicable for the type list.
(y[2:]-y[0:-2])/(x[2:]-x[0:-2])
y[2:] slices a list and returns a list. y[0:-2] slices also a list and returns a list. So there you have 2 lists.
y[2:] (a list) -(your operator) y[0:-2] (a list)
And list - list is not defined (there is no syntax for: 'listObject' - 'listObject').
BUT: the + operator is defined for lists (example):
l = ["ja"]
m = ["nein"]
n = l + m
print n
# output: ['ja', 'nein']
Take a look here for these different kind of possible operators:
https://docs.python.org/2/library/stdtypes.html
As explained in the other answers, you can not subtract regular Python lists. So why does it work the first time, and fails the second? Let's take a look at the code.
t, hp, hn = np.loadtxt(...)
...
def c_d(order, x, y):
dy = [0.0] * order
dy[ 0] = (y[1] -y[0]) / (x[ 1]-x[0])
dy[-1] = (y[-1]-y[-2]) / (x[-1]-x[-2])
dy[1:-1] = (y[2:]-y[0:-2]) / (x[2:]-x[0:-2])
return dy
z = c_d(len(t), t, phase)
...
domega = c_d(len(t), t, z)
...
When you first call c_d, the parameters x and y seem to be numpy arrays (at least t and phase are results of numpy function calls), and for those, - is a legal operation. But inside c_d, you create and finally return a regular Python list, dy, so when you then call c_d again with the result of the first call as y, this part y[2:]-y[0:-2] will fail, as y now is a regular list.
Make sure your dy is a numpy array, too, i.e. dy = np.array([0.0] *order) or just dy = np.zeros(order), then it should work.
As stated by Cyber and ProgrammingIsAwsome the error is on line
(y[2:]-y[0:-2])/(x[2:]-x[0:-2])
where you actually try to substract lists.
You could write explicitely :
for i in range(1, order - 1):
dy[i]=(y[i+1]-y[i-1])/(x[i+1]-x[1-1])