Similar subroutine statement - python

I have a code in Python.
My maincode calla a function matrixD:
def matrixD(n,x):
C=[]
for i in range(n):
C += [1.0]
C[0]=2.0
C[n-1]=2.0
D=[[0] * n for i in range(n)]
for i in range(n):
for j in range(n):
if i==j and i!=0 and i!=(n-1):
D[i][i] = -x[i]/(2.0*(1.0-x[i]**2))
else:
if i!=j:
D[i][j] = (C[i]/C[j])*(-1.0)**(i+1+j+1)/(x[i]-x[j])
# D[i][j] = 2.0
D[0][0] = (2.0*float(n-1)**2 + 1.0)/6.0
D[n-1][n-1] = -(2.0*float(n-1)**2 + 1.0)/6.0
return D
This function returns the value of D (a matrix).
But in this way D is not a global variable.
How can I make D a global variable?
Every time when I want to use D, I want to call the function and is not the ideal.
I want some similar subroutine in Fortran. You call just one time and you have a global variable.
*I am very new at Python

Related

Changing a list (passed as a function parameter) changes the list with the same name in the previous function call

Recently a friend of mine asked me to explain a strange behavior in a piece of code originally intended to count permutations using recursion. There were many improvements that could be made to the code, which I noted, but these seemed to not have any real impact.
I simplified the code down to the following, which reproduces only the problem, and not the permutations.
def foo(bar, lst):
if(bar == 1):
lst.append(0)
return
print(lst)
foo(1, lst)
print(lst)
foo(2, [])
The output is
[]
[0]
I tried lst += [0] or deleting lst after appending 0, but these did not help. Doing lst2 = lst.copy() followed by lst2.append(0) gave the expected result of two []s, however. I am confused as to why appending 0 (or any value) to lst where bar == 1 would have an effect on the lst where bar == 2. I do not consider myself a total beginner to Python, and I usually can determine the behavior of local variables. This has baffled me though. An explanation would be really appreciated.
In case you want the original code, though I don't think it'll give much more info, here it is:
A = 0
A2 = 0
NN = 3
def P(N, C):
global A
Temp = [X for X in range(1, NN + 1) if X not in C]
if(N == 1):
C.append(None)
A += 1
return
for e in Temp:
C.append(e)
P(N - 1, C)
del C[-1]
def P2(N, C):
global A2
Temp = [X for X in range(1, NN + 1) if X not in C]
if(N == 1):
A2 += 1
return
for e in Temp:
C.append(e)
P2(N - 1, C)
del C[-1]
P(NN, [])
P2(NN, [])
print(A, A2, sep = " ")
print(A == A2)

I am passing a set of N values to a loop but cant get it to print an ouput

I cannot seem to get an output when I pass numbers to the function. I need to get the computed value and subtract it from the exact. Is there something I am not getting right?
def f1(x):
f1 = np.exp(x)
return f1;
def trapezoid(f,a,b,n):
'''Computes the integral of functions using the trapezoid rule
f = function of x
a = upper limit of the function
b = lower limit of the function
N = number of divisions'''
h = (b-a)/N
xi = np.linspace(a,b,N+1)
fi = f(xi)
s = 0.0
for i in range(1,N):
s = s + fi[i]
s = np.array((h/2)*(fi[0] + fi[N]) + h*s)
print(s)
return s
exactValue = np.full((20),math.exp(1)-1)
a = 0.0;b = 1.0 # integration interval [a,b]
computed = np.empty(20)
E=np.zeros(20)
exact=np.zeros(20)
N=20
def convergence_tests(f, a, b, N):
n = np.zeros(N, 1);
E = np.zeros(N, 1);
Exact = math.exp(1)-1
for i in range(N):
n[i] = 2^i
computed[i] = trapezoid(f, a, b, n[i])
E = abs(Exact - computed)
print(E, computed)
return E, computed
You have defined several functions, but your main program never calls any of them. In fact, your "parent" function convergence_test cannot be called, because it's defined at the bottom of the program.
I suggest that you use incremental programming: write a few lines; test those before you proceed to the next mini-task in your code. In the posting, you've written about 30 lines of active code, without realizing that virtually none of it actually executes. There may well be several other errors in this; you'll likely have a difficult time fixing all of them to get the expected output.
Start small and grow incrementally.

Fastest way to add/multiply two floating point scalar numbers in python

I'm using python and apparently the slowest part of my program is doing simple additions on float variables.
It takes about 35seconds to do around 400,000,000 additions/multiplications.
I'm trying to figure out what is the fastest way I can do this math.
This is how the structure of my code looks like.
Example (dummy) code:
def func(x, y, z):
loop_count = 30
a = [0,1,2,3,4,5,6,7,8,9,10,11,12,...35 elements]
b = [0,11,22,33,44,55,66,77,88,99,1010,1111,1212,...35 elements]
p = [0,0,0,0,0,0,0,0,0,0,0,0,0,...35 elements]
for i in range(loop_count - 1):
c = p[i-1]
d = a[i] + c * a[i+1]
e = min(2, a[i]) + c * b[i]
f = e * x
g = y + d * c
.... and so on
p[i] = d + e + f + s + g5 + f4 + h7 * t5 + y8
return sum(p)
func() is called about 200k times. The loop_count is about 30. And I have ~20 multiplications and ~45 additions and ~10 uses of min/max
I was wondering if there is a method for me to declare all these as ctypes.c_float and do addition in C using stdlib or something similar ?
Note that the p[i] calculated at the end of the loop is used as c in the next loop iteration. For iteration 0, it just uses p[-1] which is 0 in this case.
My constraints:
I need to use python. While I understand plain math would be faster in C/Java/etc. I cannot use it due to a bunch of other things I do in python which cannot be done in C in this same program.
I tried writing this with cython, but it caused a bunch of issues with the environment I need to run this in. So, again - not an option.
I think you should consider using numpy. You did not mention any constraint.
Example case of a simple dot operation (x.y)
import datetime
import numpy as np
x = range(0,10000000,1)
y = range(0,20000000,2)
for i in range(0, len(x)):
x[i] = x[i] * 0.00001
y[i] = y[i] * 0.00001
now = datetime.datetime.now()
z = 0
for i in range(0, len(x)):
z = z+x[i]*y[i]
print "handmade dot=", datetime.datetime.now()-now
print z
x = np.arange(0.0, 10000000.0*0.00001, 0.00001)
y = np.arange(0.0, 10000000.0*0.00002, 0.00002)
now = datetime.datetime.now()
z = np.dot(x,y)
print 'numpy dot =',datetime.datetime.now()-now
print z
outputs
handmade dot= 0:00:02.559000
66666656666.7
numpy dot = 0:00:00.019000
66666656666.7
numpy is more than 100x times faster.
The reason is that numpy encapsulates a C library that does the dot operation with compiled code. In the full python you have a list of potentially generic objects, casting, ...

Dynamic programming solution to maximizing an expression by placing parentheses

I'm trying to implement an algorithm from Algorithmic Toolbox course on Coursera that takes an arithmetic expression such as 5+8*4-2 and computes its largest possible value. However, I don't really understand the choice of indices in the last part of the shown algorithm; my implementation fails to compute values using the ones initialized in 2 tables (which are used to store maximized and minimized values of subexpressions).
The evalt function just takes the char, turns it into the operand and computes a product of two digits:
def evalt(a, b, op):
if op == '+':
return a + b
#and so on
MinMax computes the minimum and the maximum values of subexpressions
def MinMax(i, j, op, m, M):
mmin = 10000
mmax = -10000
for k in range(i, j-1):
a = evalt(M[i][k], M[k+1][j], op[k])
b = evalt(M[i][k], m[k+1][j], op[k])
c = evalt(m[i][k], M[k+1][j], op[k])
d = evalt(m[i][k], m[k+1][j], op[k])
mmin = min(mmin, a, b, c, d)
mmax = max(mmax, a, b, c, d)
return(mmin, mmax)
And this is the body of the main function
def get_maximum_value(dataset):
op = dataset[1:len(dataset):2]
d = dataset[0:len(dataset)+1:2]
n = len(d)
#iniitializing matrices/tables
m = [[0 for i in range(n)] for j in range(n)] #minimized values
M = [[0 for i in range(n)] for j in range(n)] #maximized values
for i in range(n):
m[i][i] = int(d[i]) #so that the tables will look like
M[i][i] = int(d[i]) #[[i, 0, 0...], [0, i, 0...], [0, 0, i,...]]
for s in range(n): #here's where I get confused
for i in range(n-s):
j = i + s
m[i][j], M[i][j] = MinMax(i,j,op,m,M)
return M[0][n-1]
Sorry to bother, here's what had to be improved:
for s in range(1,n)
in the main function, and
for k in range(i, j):
in MinMax function. Now it works.
The following change should work.
for s in range(1,n):
for i in range(0,n-s):

Python programming beginner difficulties

I am trying to write a program in Python, but I am stuck in this piece of code:
def function():
a=[3,4,5,2,4]
b=1
c=0
for x in range(5):
if a[x-1]>b:
c=c+1
return c
print(function())
It gives me value 1 instead of 5. Actually the function I am trying to write is a little bit more complicated, but the problem is actually the same, it doesn't give me the right result.
def result():
r=[0]*len(y)
a=2
b=an_integer
while b>0:
for x in range(len(y)) :
if y[x-1] > 1/a and b>0:
r[x-1]=r[x-1]+1
b=b-1
a=a+1
return r
print(result())
v is a list of values smaller than 1 and b has an integer as value. If some values x in v are bigger than 1/a then the values x in r should get 1 bigger, then it should repeat a=a+1 until b becomes 0. I want this function to give a result of the type for ex. [7,6,5,4,3] where the sum of the elements in this list is equal to b.
Sometimes it gives me the right value, sometimes not and when the elements in v are equal for example v=[0.33333,0.33333,0.33333] it gets stuck and doesn't give me a result.
I don't know what I am doing wrong !
Your return statements are incorrectly indented. You want to return after the loop ends, not inside the loop.
def function():
a = [3, 4, 5, 2, 4]
b = 1
c = 0
for x in range(5):
if a[x-1] > b:
c = c + 1
return c
Also, a couple of optimizations to the code:
def function(a, b):
c = 0
for x in a:
if x > b:
c += 1
return c
or further:
def function(a, b):
return sum(x > b for x in a)
return; only inside the fun in the end it.
and name the Variable v

Categories

Resources