Adding Pivoting to the following Gauss Elimination code - python-3.x

The program below uses gauss elimination to without pivoting. I would like to know how to add pivoting into this code to account for an array with a leading term of zero
from numpy import array,empty
A = array([[ 2, 1, 4, 1 ],
[ 3, 4,-1,-1 ],
[ 1, -4, 1, 5],
[2,-2,1,3]],float)
v = array([ -4,3,9,7 ], float)
N = len(v)
for m in range (N):
div = A[m,m]
A[m,:] /= div
v[m] /= div
for i in range(m+1,N):
mult = A[i,m]
A[i,:] -= mult*A[m,:]
v[i] -= mult*v[m]
x = empty(N,float)
for m in range(N-1,-1,-1):
x[m] = v[m]
for i in range(m+1,N):
x[m] -= A[m,i]*x[i]
the new array I would like it to solve is
A = array([[ 0, 1, 4, 1 ],
[ 3, 4,-1,-1 ],
[ 1, -4, 1, 5],
[2,-2,1,3]],float)

Related

Remove non-conjugates from complex numbers list

I have two lists, one contains the real part of imaginary numbers, the other contains the imaginary part of the same numbers. I want to remove from both lists the imaginary numbers that do not have a conjugate.
For example, the following lists x = [3, 4, 2, 7, 4] and y = [2, -1, 0, 6, 1] represent the numbers :
3 + 2j <- no conjugate (to remove)
4 - 1j <- conjugate (to keep)
2 + 0j <- real (to keep)
4 + 1j <- conjugate (to keep)
7 + 6j <- no conjugate (to remove)
The expected result is the following :
new_x = [4, 2, 4]
new_y = [-1, 0, 1]
Any idea how i can achieve this ? Thanks
This script will find complex conjugates from lists x and y:
x = [3, 4, 2, 7, 4]
y = [2, -1, 0, 6, 1]
tmp = {}
for r, i in zip(x, y):
tmp.setdefault(i, set()).add(r)
x_out, y_out = [], []
for r, i in zip(x, y):
if i==0 or r in tmp.get(-i, []):
x_out.append(r)
y_out.append(i)
print(x_out)
print(y_out)
Prints:
[4, 2, 4]
[-1, 0, 1]

python row dividing with one element

I am reading 'Computational Physics -Mark Newman' book.
The following is one of its example.
from numpy import *
A = array([
[2, 1, 4, 1],
[3, 4, -1, -1],
[1, -4, 1, 5],
[2, -2, 1, 3]
])
v = array([-4, 3, 9, 7], float)
N = len(v)
for m in range(N):
div = A[m,m]
A[m,:] /= div <-----------(not working)
v[m] /= div
...
It is one part of back-substitution implementation.
But while dividing div(diagonal element of row in matrix), it shows error.
"A[m,:] /= div
TypeError: No loop matching the specified signature and casting was found for ufunc true_divide"
What made this error? How can i fix it?
This should fix it:
import numpy as np
A = np.array([
[2, 1, 4, 1],
[3, 4, -1, -1],
[1, -4, 1, 5],
[2, -2, 1, 3]
], dtype=np.float)
v = np.array([-4, 3, 9, 7], float)
N = len(v)
for m in range(N):
div = A[m, m]
A[m, :] /= div
v[m] /= div
Or if you really want integer division:
for m in range(N):
div = A[m, m]
A[m, :] = A[m, :] / div
v[m] /= div
The issue is that in Python 3, / does the true division, so it convert the results to float, and when you do A[m, :] /= div you are trying to assign a float result to A which is of type integer. You can find more information on this, here
As a side-note is generally better not to use:
from numpy import *

What is this operation in numpy called?

I've been going over the numpy docs looking for a specific operation. The words I would use for this are "overlay" or "mask" but the numpy concepts of those words don't seem to match mine.
I want to take two arrays, one dense and one sparse and combine them thusly:
[ 1, 2, 3, 4, 5 ]
X [ N, N, 10, N, 12 ]
= [ 1, 2, 10, 4, 12 ]
where X is the operation and N is None, or Null, -1, or some other special character.
How is this achieved in numpy/python3?
You can use np.where:
# pick special value
N = -1
dns = [ 1, 2, 3, 4, 5 ]
sprs = [ N, N, 10, N, 12 ]
# this is important otherwise the comparison below
# is not done element by element
sprs = np.array(sprs)
# tada!
np.where(sprs==N,dns,sprs)
# array([ 1, 2, 10, 4, 12])
When called with three arguments m,a,b where "mixes" a and b taking elements from a where m is True and from b where it is False.
You can "fill" the masked array, with np.ma.filled(..) [numpy-doc], for example:
>>> a
array([1, 2, 3, 4, 5])
>>> b
masked_array(data=[--, --, 10, --, 12],
mask=[ True, True, False, True, False],
fill_value=999999)
>>> b.filled(a)
array([ 1, 2, 10, 4, 12])
>>> np.ma.filled(b, a)
array([ 1, 2, 10, 4, 12])
Here we thus fill the masked values from b with the corresponding values of a.

"outer" in python similar to Mathematica

I have an array of 2D positions (x,y) of a few particles. In Mathematica, I can use
Outer[Subtract, pos, pos, 1]
If pos is an array of shape (n,2) where n is the number of particles, the result of the above Mathematia code is a n x n x 2 array and each [i,j] element of this matrix is the result of (x_i - x_j, y_i - y_j) operation.
For example
pos = {{x1, y1}, {x2, y2}, {x3, y3}};
Outer[Subtract, pos, pos, 1]
gives
{
{{0, 0}, {x1 - x2, y1 - y2}, {x1 - x3, y1 - y3}}
,
{{-x1 + x2, -y1 + y2}, {0, 0}, {x2 - x3, y2 - y3}}
,
{{-x1 + x3, -y1 + y3}, {-x2 + x3, -y2 + y3}, {0, 0}}
}
which is a 3x3x2 array. However, in python I could not get similar results:
import numpy as np
pos = [[1, 2], [5, 6], [8, 9]]
print (np.subtract.outer(pos, pos).shape)
gives (3, 2, 3, 2), and np.subtract.outer(pos, pos) is
array([[[[ 0, -1],
[-4, -5],
[-7, -8]],
[[ 1, 0],
[-3, -4],
[-6, -7]]],
[[[ 4, 3],
[ 0, -1],
[-3, -4]],
[[ 5, 4],
[ 1, 0],
[-2, -3]]],
[[[ 7, 6],
[ 3, 2],
[ 0, -1]],
[[ 8, 7],
[ 4, 3],
[ 1, 0]]]])
while for similar values the Mathemtica code gives what I need, that is
{
{{0, 0}, {-4, -4}, {-7, -7}}
,
{{4, 4}, {0, 0}, {-3, -3}}
,
{{7, 7}, {3, 3}, {0, 0}}
}
you are looking for:
pos = np.array(pos)
pos[:,None]-pos
You can also achieve the same by:
np.squeeze([i-pos for i in pos])
EDIT:
For normalization, you can do:
ss = np.linalg.norm(pos_diff,axis = 2,keepdims = True)
ss[ss==0] = 1
pos_diff/ss
numpy.ufunc.outer(a,b) will calculate each possible combination with one element from a and another from b. One option is to carry out calculations for the x and y coordinates separately and then remerge the result:
pos = np.array([[1, 2], [5, 7], [8, 13]])
dx = np.subtract.outer(pos[:,0],pos[:,0])
dy = np.subtract.outer(pos[:,1],pos[:,1])
result=np.transpose([dx,dy], axes=(1,2,0))
(I changed the values in pos so that the result is less symmetric.)
Edit: As compared to calculating and storing useless x_i-y_j by acting subtract.outer on the whole arrays then using squeeze afterwards, this solution is significantly more effective for large arrays.

calculation of variance function equation

I have an error in this code as I want to calculate the variance between the values in the(x1) and (x2) list. any recommendation?!
def my_var(L):
s = 0
t = 0
u = 0
for i in range(0, len(L)):
s += L[i]
t = s/len(L)
u += ((L[i]-t)*(L[i]-t))
return u / len(L)
x1 = [1, 3, 4, -3, 8]
x2 = [1, -4, 7, 2]
v1 = my_var(x1)
v2 = my_var(x2)
print(v1)
print(v2)
You're doing many things incorrectly based on how I learned prob and stats. You need to calculate the average (mean) and then sum each value subtracted by the mean, squared. Then finally take that numerator and divide by 1 less than the sample size (n-1).
def my_var(L):
mean = float(sum(L) / Len(L))
numerator = 0
for i in range(0, len(L)):
numerator += (L[i]-mean)**2
return numerator / (len(L) - 1)
x1 = [1, 3, 4, -3, 8]
x2 = [1, -4, 7, 2]
v1 = my_var(x1)
v2 = my_var(x2)
print(v1)
print(v2)
Without using sum:
def my_var(L):
my_sum = 0
mean = 0
numerator = 0
for i in range(0, len(L)):
my_sum += L[i]
mean = float(my_sum / len(L))
for i in range(0, len(L)):
numerator += (L[i]-mean)**2
return numerator / (len(L) - 1)
x1 = [1, 3, 4, -3, 8]
x2 = [1, -4, 7, 2]
v1 = my_var(x1)
v2 = my_var(x2)
print(v1)
print(v2)
Try numpy.
import numpy as np
x1 = [1, 3, 4, -3, 8]
x2 = [1, -4, 7, 2]
v1 = np.var(x1)
v2 = np.var(x2)
Thank you #billy_ferguson. I have modified your code and it works. Execuse me, I am still an amateur but could you replace float and sum function and use simpler arithmetic operators as len(L) and += in this line mean = float(sum(L) / len(L))
def my_var(L):
mean = 0
numerator = 0
for i in range(0, len(L)):
mean = float(sum(L) / len(L))
numerator += (L[i]-mean)**2
return numerator / len(L)
x1 = [1, 3, 4, -3, 8]
x2 = [1, -4, 7, 2]
v1 = my_var(x1)
v2 = my_var(x2)
print(v1)
print(v2)

Resources