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.
Related
The Problem occurs in line 29:
It is a Type Error
I can't figure out where I went wrong with my parameters. It should assign every a[i][k] with a value but it just ends up with the following error message:
a[i][k].append(g * m[i] * dr[k]/d3)
TypeError: 'int' object is not subscriptable
Here the full code:
import numpy as np
from numpy import absolute
from numpy import power
r = [[1,1,1],[1,1,1],[0,0,0]]
v = [[0,0,0],[0,0,0],[0,0,0]]
a = [[0,0,0],[0,0,0],[0,0,0]]
m = [1,1,1]
O = -1
N = 3
def beschleunigung(O, N, m, r, a):
i = 0
k = 0
dr = [0,0,0]
d3 = 0
g = 1
for k in range(1,3):
a[i][k] = 0
for i in range(1,N):
if i != O:
for k in range(1,3):
a = (r[i][k])
b = (r[0][k])
dr[k] = a - b
d3 = np.power(np.absolute(dr),3)
for k in range(1,3):
a[i][k].append(g * m[i] * dr[k]/d3)
beschleunigung(O,N,m,r,a)
print(a[1])
When your code executes the line a = (r[i][k]), a becomes an integer, rather than a list of lists as it was in the input to this function. This causes your append to fail as you cannot append to an integer.
I expect that you intended to create another variable to use in your subtraction with b - make sure to use a name that is not already defined in your scope.
A simple function returns error :"'function' object does not support item assignment"
Can I fix that without making a Class?
import numpy as np
def board(n):
return ( np.ones((n,n)))
def cdiag(brd,i,j,n):
m = i
l = i
for k in range(j+1,n-1,1):
m = m-1
l = l+1
if m >=0:
brd[m, k] = 0.
if l < n:
brd[l,k]=0
return
myboard = board(8)
print(myboard)
cdiag(myboard, 0,4,8)
print(myboard)
line : brd[m, k] = 0 returns error:
TypeError: 'function' object does not support item assignment
Thank you Guys!!
Have retyped the thing and now it is working.
Still do not know what was wrong before
Referring to my code below (only the relevant part of original code), since x0 is a 4 X 3 array, x should also be the same. But I get an 'invalid index to scalar variable' error in constraint1.
I wrote the constraints iteratively as done in the answer in scipy.optimize.minimize (COBYLA and SLSQP) ignores constraints initiated within for loop
Any better (general) way to write the constraints would be great. Thanks in advance!
I need the loop for the constraints as this is just a toy optimization problem and not the original optimization problem(Game theory) I wish to solve.
The code(link to complete code below):
def constraint1(i):
def g(x):
con = 20
for k in range(3):
con = con - x[i][k]
return con
return g
x0 = np.array([[5,5,5],[5,5,5],[5,5,5],[5,5,5]])
cons = []
for i in range(4):
cons.append({'type': 'ineq', 'fun': constraint1(i)})
solution = minimize(objective,x0,method='SLSQP',\
bounds=None,constraints=cons)
And the error (Please ignore the line numbers as the above is a part of a slightly bigger code):
Traceback (most recent call last):
File "opt.py", line 44, in <module>
bounds=None,constraints=cons)
File "C:\Users\dott\Anaconda2\lib\site-packages\scipy\optimize\_minimize.py", line 458, in minimize constraints, callback=callback, **options)
File "C:\Users\dott\Anaconda2\lib\site-packages\scipy\optimize\slsqp.py", line 312, in _minimize_slsqp
mieq = sum(map(len, [atleast_1d(c['fun'](x, *c['args'])) for c in cons['ineq']]))
File "opt.py", line 15, in g
con = con - x[i][k]
IndexError: invalid index to scalar variable.
The complete code: https://pastebin.com/cvYBvW3B
It seems that optimization task flatten your initial guess and return after each iteration flattened solution array (instead of 4x3 array it returns 1x12 array). That's why you get this kind of error. You should reshape your x array in objective and constraints functions from 1x12 to 4x3. After that, you can access second dimension of x variable and avoid IndexError: invalid index to scalar variable.. Your functions should be like this:
def objective(x):
global q
sum = 0
x = x.reshape((4, 3))
for i in range(4):
for j in range(3):
sum = sum + x[i][j]*q[i][j]
return -1*sum
def constraint1(i):
def g(x):
con = 20
x = x.reshape((4, 3))
for k in range(3):
con = con - x[i][k]
return con
return g
def constraint2(k):
def h(x):
sum_eq = 20
x = x.reshape((4, 3))
for i in range(4):
sum_eq = sum_eq - x[i][k]
return sum_eq
return h
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 have written the following code in python 2.7 in order to calculate an integration numerically and then use the result of this integration for further steps of the project.
import numpy as np
from scipy import linspace,logspace
from cosmicpy import *
Omega_Matter, Omega_DarkEnergy, A, b, rho_critical, m = 0.306, 0.694, 0.3222, 0.707, 2.77536627e+11, 1000000
def D(z):
a = 1/(1+z)
x = (Omega_DarkEnergy/Omega_Matter)**(1/3)*a
return (5/2)*(Omega_Matter/Omega_DarkEnergy)**(1/3)*x**(-3/2)*(1+x**3)**(1/2)* \
(x**2/(3*x**3 + 3) - np.log(x + 1)/9 + np.log(x**2 - x + 1)/18 \
+ np.sqrt(3)*np.arctan(2*np.sqrt(3)*x/3 \
- np.sqrt(3)/3)/9 + np.sqrt(3)*np.pi/54)
def delta(z):
return D(z)/D(0)
def W(k, M):
rho_m = rho_critical*Omega_Matter
R = (3*M/(4*np.pi*rho_m))**(1/3)
x = k*R
return (3/x)*(sin(x)-x*cos(x))
my_cosmology = cosmology(Omega_m=0.306, Omega_de=0.694, h=0.679, Omega_b=0.0483, n=0.968, tau=0.067, sigma8=0.815, w=-1)
k_array = np.logspace(-16,4,m)
P = my_cosmology.pk_lin(k_array)
def sigma_squared(z, M):
dk = (np.max(k_array)-np.min(k_array))/(m-1)
summation = []
for k in k_array:
Integral = 0
Integrand = k**2*P[k]*(W(k, M))**2
Integral += dk * np.sum(Integrand[k])
summation.append(Integral)
return ((delta(z))**2/(2*(np.pi)**2))*summation[-1]
print(summation)
sigma_squared(0.01, 1e+9)
As I write more of the code, I check my steps one by one by getting a print and see if the output is what I expect. However, I am unable to produce the final product of the last function which is supposed to be a value given the values for the variables z and M. In particular I am sure that something is wrong with the integration inside that function because I am not getting any thing for print(summation) which is supposed to be a big 1d array whose last element print(summation[-1])should give me the area under the curve (upto a pre-factor defined in the final return of the function). Here is the error message and I couldn't find any on-line source for the particular error message I am getting. Your help is greatly appreciated.
mycode.py:95: VisibleDeprecationWarning: using a non-integer number
instead of an integer will result in an error in the future
Integrand = k**2*P[k]*(W(k, M))**2 Traceback (most recent call last):
File "mycode.py", line 102, in
sigma_squared(0.01, 1e+9) File "mycode.py", line 96, in sigma_squared
Integral += dk * np.sum(Integrand[k]) TypeError: 'Zero' object has no attribute 'getitem'
Edited Code (which is too slow to know if it is working correctly):
k_array = np.logspace(-16,4,m)
my_cosmology = cosmology(Omega_m=0.306, Omega_de=0.694, h=0.679, Omega_b=0.0483, n=0.968, tau=0.067, sigma8=0.815, w=-1)
P = my_cosmology.pk_lin(k_array)
M_array = np.logspace(8,16,n)
def W(k, M):
rho_m = rho_critical*Omega_Matter
R = (3*M/(4*np.pi*rho_m))**(1/3)
y = k*R
return (3/y**3)*(sin(y)-y*cos(y))
def sigma_squared(z, M):
dk = (np.max(k_array)-np.min(k_array))/(m-1)
summation = []
for k in k_array:
for M in M_array:
Integral = 0
Integrand = k**2*P[k]*(W(k, M))**2
Integral += dk * np.sum(Integrand)
summation.append(Integral)
return ((delta(z))**2/(2*(np.pi)**2))*summation[-1]
print(sigma_squared(0, 1e+9))