Function call changing its argument python - python-3.x

I am trying to reduce a matrix to its echlon form using a function but upon the calling the function, it is also changing its arguments. Here is the code
def GaussE(E,r):
N = np.size(r)
for i in range(0,N-1):
for j in range(i+1,N):
f=(E[j,i]/E[i,i])
r[j]= r[j] -(f)*r[i]
for k in range(i,N):
E[j,k] = E[j,k]-(f*E[i,k])
return(E,r)
A = np.array([[5.10,8.70],[2.40,4.10]])
b = np.array([9.48,4.48])
print(A,b)
output: [[ 5.1 8.7] [ 2.4 4.1]] [ 9.48 4.48]
X = GaussE(A[:],b[:])
print(A,b) # Why is A and b changing? they should not change
output:[[ 5.10000000e+00 8.70000000e+00]
[ 0.00000000e+00 5.88235294e-03]] [ 9.48 0.01882353]

In python every variable refers to an object. It refers to the object pointer so it is using the object itself.
In that function you are referencing E like E[j,k] and r like r[j] and assigning to it which means you are using that same object and means you are manipulating it.
Try to use copy at the first of your function (from copy import copy)
from copy import copy
def GaussE(E,r):
E = copy(E)
r = copy(r)
N = np.size(r)
for i in range(0,N-1):
for j in range(i+1,N):
f=(E[j,i]/E[i,i])
r[j]= r[j] -(f)*r[i]
for k in range(i,N):
E[j,k] = E[j,k]-(f*E[i,k])
return(E,r)
A = np.array([[5.10,8.70],[2.40,4.10]])
b = np.array([9.48,4.48])
print(A,b)

Related

inner function changing the variable value of outer function

def swap(i,r,c,mat):
for j in range(i+1,c):
if(abs(mat[j][j])>0):
mat[[j,i]] = mat[[i,j]]
break
return mat
def upper_triMat(matA,r,c):
np.set_printoptions(precision=4)
# forward elimination
for i in range(0,c-1):
if matA[i][i] == 0:
matA = swap(i,r,c,matA)
for j in range(i+1,r):
multiplier = matA[j][i]/matA[i][i]
for k in range(0,c):
matA[j][k] = matA[j][k] - multiplier*matA[i][k]
return matA
def dolittle(A):
A = np.array(A)
r,c = np.shape(A)
print(A)
U = upper_triMat(A,r,c) # Here the value of A is changed U.
print(A)
l = np.eye(r,c)
for i in range(0,r-1):
for j in range(i+1,r):
sum = 0
for k in range(0,r):
if i != k:
sum = sum + U[k][i]*l[j][k]
l[j][i] = (A[j][i]-sum)/U[i][i]
return l,U
A = [[3,-0.1,-0.2],
[0.1,7,-0.3],
[0.3,-0.2,10]]
dolittle(A)
When i call the upper_triMat function "A" changes in dolittle function. Why?? A is A and the upper_triMat function assigning it to U. But A is also getting the value of U. Using Jupyter Notebook. I am doing LU decomposition
upper_triMat mutates its parameter matA. And since matA is a reference to A, it's being modified.
Maybe you could fix it that way
U = upper_triMat(A.copy(),r,c) # pass a copy of the list instead of the reference of the original one.

how do i write multiple function outputs to single csv file

i am scraping multiple websites so i am using one function for each website script, so each function returns 4 values, i want to print them in dataframe and write them in csv but i am facing this problem, i may be asking something too odd or basic but please help
Either i will have to write whole script in one block and that will look very nasty to handle so if i could find a way around, this is just a sample of problem i am facing..
def a1(x):
z=x+1
r = x+2
print(z, r)
def a2(x):
y=x+4
t=x+3
print(y, t)
x = 2
a1(x)
a2(x)
3 4
6 5
data = pd.Dataframe({'first' : [z],
'second' : [r],
'third' : [y],
'fourth' : [t]
})`
data
*error 'z' is not defined*
You may find it convenient to write functions that return a list of dicts.
For example:
rows = [dict(a=1, b=2, c=3),
dict(a=4, b=5, c=6)]
df = pd.DataFrame(rows)
The variables are only defined in the local scope of your functions, you'd either need to declare them globally or - the better way - return them so you can use them outside of the function by assigning the return values to new variables
import pandas as pd
def a1(x):
z = x+1
r = x+2
return (z, r)
def a2(x):
y = x+4
t = x+3
return (y, t)
x = 2
z, r = a1(x)
y, t = a2(x)
data = pd.DataFrame({'first' : [z],
'second' : [r],
'third' : [y],
'fourth' : [t]
})

Assigning multiple expressions for Symbolic variable in theano

a = T.iscalar()
b = T.iscalar()
c = a
d = c+b
f = theano.function(
inputs=[a,b],
outputs=d
)
print(f(2,3))
This piece of code is executing properly and is printing 5. But if I change the code as below,
a = T.iscalar()
b = T.iscalar()
e = T.iscalar()
c = a
d = c+b
c = e
f = theano.function(
inputs=[e,b],
outputs=d
)
print(f(2,3))
I'm getting the following error:
theano.compile.function_module.UnusedInputError: theano.function was asked to create a function computing outputs given certain inputs, but the provided input variable at index 0 is not part of the computational graph needed to compute the outputs:
It seems that c is depending only on a and not on e.
My question is, Does theano allows only one expression for the assignment of a symbolic variable?

How to apply multiprocessing in python3.x for the following nested loop

for i in range(1,row):
for j in range(1,col):
if i > j and i != j:
x = Aglo[0][i][0]
y = Aglo[j][0][0]
Aglo[j][i] = offset.myfun(x,y)
Aglo[i][j] = Aglo[j][i]
Aglo[][] is a 2D array, which consists of lists in the first row
offset.myfun() is a function defined elsewhere
This might be a trivial question but i couldn't understand how to use multiprocessing for these nested loops as x,y (used in myfun()) is different for each process(if multiprocessing is used)
Thank you
If I'm reading your code right, you are not overwriting any previously calculated values. If that's true, then you can use multiprocessing. If not, then you can't guarantee that the results from multiprocessing will be in the correct order.
To use something like multiprocessing.Pool, you would need to gather all valid (x, y) pairs to pass to offset.myfun(). Something like this might work (untested):
pairs = [(i, j, Aglo[0][i][0], Aglo[j][0][0]) for i in range(1, row) for j in range(1, col) if i > j and i != j]
# offset.myfun now needs to take a tuple instead of x, y
# it additionally needs to emit i and j in addition to the return value
# e.g. (i, j, result)
p = Pool(4)
results = p.map(offset.myfun, pairs)
# fill in Aglo with the results
for pair in pairs:
i, j, value = pair
Aglo[i][j] = value
Aglo[j][i] = value
You will need to pass in i and j to offset.myfun because otherwise there is no way to know which result goes where. offset.myfun should then return i and j along with the result so you can fill in Aglo appropriately. Hope this helps.

Why am i getting a list index out of range error in my code?

The error occurs in line if data[l][0] == value:
def binary_pairs(data, value):
l = 0
h = len(data) - 1
while l < h and data[l]!= value:
m = (h + l) // 2
if data[m][0] == value:
l = m
elif data[m][0] < value:
l = m + 1
else:
h = m - 1
print("done")
if data[l][0] == value:
return l
else:
return -1
example input:
[ [ "dead", ["brian.txt","grail.txt"] ],
[ "eunt", ["brian.txt"] ],
[ "spank", ["grail.txt"] ]
]
I can see two potential issues with your code:
It seems odd that you use both data[l] and data[l][0] in comparisons.
If, for example, l==0 and h==1 and you end up taking the else (h = m - 1), you'd end up with h==-1, which is out of bounds. There could be other similar issues.
I can't run your code right now but here are a few ideas.
If you are trying to solve a problem, rather than trying to learn to write a binary search, consider using Python's bisect module.
http://docs.python.org/2/library/bisect.html
It is best practice in Python to comply with the coding standard called PEP 8; this recommends not using lower-case L as a variable name, or upper-case I.
http://www.python.org/dev/peps/pep-0008/
It would be cleaner to have the loop immediately return the index when it finds the value, rather than having the loop test at the top to make sure the value hasn't been found yet, causing the loop to end and then the value to be returned from the bottom of the function. If the loop ends, you can return -1 at the end of the function.
Your loop checks that the index is < h but does not check that the index is I >= 0. I suspect that this could be your problem.
When debugging a loop like this, it is often helpful to add print statements that log what is going on. You should print the value of the index, and print enough other lines to know whether it is being increased or decreased, and by how much.

Resources