Different Output in matrix Multiplication Python vs Swift - python

I'm writing a code of matrix multiplication in swift and python but both code generate a different output.
I also write this code in C++ but it generate same output as in python, I checked swift code again and again but I got no difference
I'm trying to multiply these two matrix
Matrix A
1 0 1
0 0 0
1 0 1
Matrix B
0 0 0 0 0 0 0 0 0 0
0 1 2 3 4 5 6 7 8 0
0 2 3 4 5 6 7 8 9 0
0 3 4 5 6 7 8 9 5 0
0 4 5 6 7 8 9 3 4 0
0 4 5 6 7 8 9 2 3 0
0 5 6 7 8 9 0 4 6 0
0 6 7 8 9 1 2 3 8 0
0 7 8 9 1 2 3 0 5 0
0 8 9 2 4 5 6 4 8 0
0 0 0 0 0 0 0 0 0 0
Here's my Python Code
row,col = 8,9
result = [[0 for x in range(row)] for y in range(col)]
row,col=0,0
for matrixB_Row in range(0,9):
for matrixB_Col in range(0,8):
for matrixA_Row in range(0,3):
for i in range(0,3):
for matrixA_Col in range(0,3):
result[row][col] = result[row][col]+(matrixA[matrixA_Row][matrixA_Col]*matrixA[matrixB_Row][matrixB_Col])
matrixA_Col+=1
matrixB_Row+=1
i+=1
matrixB_Col+=1
matrixB_Row = matrixB_Row-3
matrixB_Col = matrixB_Col-3
matrixA_Row+=1
col+=1
matrixB_Col+=1
row+=1
col=0
matrixB_Row=+1
matrixB_Col=0
Here's my swift code
var Row = 0, Col = 0, MatrixB_Col = 0, MatrixB_Row = 0, MatrixA_Col = 0, MatrixA_Row = 0, i = 0
var result = [[Int]](repeating: [Int](repeating: 0, count: 8), count: 9)
while MatrixB_Row < 9
{
MatrixB_Col = 0
while MatrixB_Col < 8{
MatrixA_Row = 0
while MatrixA_Row < 3 {
i = 0
while i < 3 {
MatrixA_Col = 0
while MatrixA_Col < 3{
result[Row][Col] += (matrixA[MatrixA_Row][MatrixA_Col] * matrixB[MatrixB_Row][MatrixB_Col]);
MatrixA_Col+=1
MatrixB_Row+=1
}
i+=1
MatrixB_Col+=1
MatrixB_Row = MatrixB_Row - 3
}
MatrixA_Row+=1
MatrixB_Col = MatrixB_Col - 3
}
MatrixB_Col+=1
Col+=1
}
Row+=1
Col=0
MatrixB_Row+=1
MatrixB_Col = 0
}

Multiplication in your python code:
result[row][col] = result[row][col]+(matrixA[matrixA_Row][matrixA_Col]*matrixA[matrixB_Row][matrixB_Col])
Here you're using elements only from matrix A for multiplication.
Multiplication in your swift code:
result[Row][Col] += (matrixA[MatrixA_Row][MatrixA_Col] * matrixB[MatrixB_Row][MatrixB_Col]);
Here you're using both matrix A and matrix B.
That's why the results are different - you have an error in your python code.

Can you run the numbers through this and compare?
https://github.com/raywenderlich/swift-algorithm-club/tree/master/Strassen%20Matrix%20Multiplication

Related

Replace values in df col - pandas

I'm aiming to replace values in a df column Num. Specifically:
where 1 is located in Num, I want to replace preceding 0's with 1 until the nearest Item is 1 working backwards or backfilling.
where Num == 1, the corresponding row in Item will always be 0.
Also, Num == 0 will always follow Num == 1.
Input and code:
df = pd.DataFrame({
'Item' : [0,1,2,3,4,4,0,1,2,3,1,1,2,3,4,0],
'Num' : [0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0]
})
df['Num'] = np.where((df['Num'] == 1) & (df['Item'].shift() > 1), 1, 0)
Item Num
0 0 0
1 1 0
2 2 0
3 3 0
4 4 0
5 4 1
6 0 0
7 1 0
8 2 0
9 3 0
10 1 0
11 1 0
12 2 0
13 3 0
14 4 1
15 0 0
intended output:
Item Num
0 0 0
1 1 1
2 2 1
3 3 1
4 4 1
5 4 1
6 0 0
7 1 0
8 2 0
9 3 0
10 1 0
11 1 1
12 2 1
13 3 1
14 4 1
15 0 0
First, create groups of the rows according to the two start and end conditions using cumsum. Then we can group by this new column and sum over the Num column. In this way, all groups that contain a 1 in the Num column will get the value 1 while all other groups will get 0.
groups = ((df['Num'].shift() == 1) | (df['Item'] == 1)).cumsum()
df['Num'] = df.groupby(groups)['Num'].transform('sum')
Result:
Item Num
0 0 0
1 1 1
2 2 1
3 3 1
4 4 1
5 4 1
6 0 0
7 1 0
8 2 0
9 3 0
10 1 0
11 1 1
12 2 1
13 3 1
14 4 1
15 0 0
You could try:
for a, b in zip(df[df['Item'] == 0].index, df[df['Num'] == 1].index):
df.loc[(df.loc[a+1:b-1, 'Item'] == 1)[::-1].idxmax():b-1, 'Num'] = 1

Hour Glass in Python

I'm trying to code an hour glass in python with the following format:
Sample Input = 3
Sample Output:
1 0 2 0 3
0 2 0 3 0
0 0 3 0 0
0 2 0 3 0
1 0 2 0 3
My code:
#for input use:
inputString = int(input())
# For uper half
for i in range(1,inputString):
# printing i zeroes at the
# beginning of each row
for j in range(1,i):
print("0",end=" ")
for k in range(i,inputString+1):
print(k,"0",end=" ")
print()
# For lower half
for i in range(inputString , 0, -1):
# printing i spaces at the
# beginning of each row
for j in range(1, i):
print("0", end = " ")
# printing i to rows value
# at the end of each row
for k in range(i, inputString + 1):
print(k,"0",end = " ")
print()
My Output:
1 0 2 0 3 0
0 2 0 3 0
0 0 3 0
0 2 0 3 0
1 0 2 0 3 0
I experimented with the looping parameters but I'm not able to figure it out. But unfortunately i couldn't.
Please provide some inputs.
Here's my take to your problem:
def hourglass(n, pretty_print=True):
all_lines = []
for ii in range(n):
line = np.zeros((n*2-1))
line[[idx for idx in np.arange(ii, n*2-1-ii, 2)]] = np.arange(ii+1, n+1, 1)
all_lines.append(line)
all_lines = all_lines + all_lines[-2::-1]
if pretty_print:
str_lines = [[str(int(val)) for val in line] for line in all_lines]
[print(" ".join(line)) for line in str_lines]
return np.vstack(all_lines)
In the case of n=3:
hourglass(3, pretty_print=True)
which prints:
1 0 2 0 3
0 2 0 3 0
0 0 3 0 0
0 2 0 3 0
1 0 2 0 3
One solution with recursion:
def hourglass(n, n2=1, filler_char='0'):
if n == n2:
print(*'{:{filler}^{width}}'.format(filler_char.join('{}'.format(n)), width=n*2-1, filler=filler_char), sep=' ')
return
print(*'{:{filler}^{width}}'.format(filler_char.join(str(i) for i in range(n2, n+1)), width=n*2-1, filler=filler_char), sep=' ')
hourglass(n, n2+1, filler_char)
print(*'{:{filler}^{width}}'.format(filler_char.join(str(i) for i in range(n2, n+1)), width=n*2-1, filler=filler_char), sep=' ')
hourglass(7)
Prints:
1 0 2 0 3 0 4 0 5 0 6 0 7
0 2 0 3 0 4 0 5 0 6 0 7 0
0 0 3 0 4 0 5 0 6 0 7 0 0
0 0 0 4 0 5 0 6 0 7 0 0 0
0 0 0 0 5 0 6 0 7 0 0 0 0
0 0 0 0 0 6 0 7 0 0 0 0 0
0 0 0 0 0 0 7 0 0 0 0 0 0
0 0 0 0 0 6 0 7 0 0 0 0 0
0 0 0 0 5 0 6 0 7 0 0 0 0
0 0 0 4 0 5 0 6 0 7 0 0 0
0 0 3 0 4 0 5 0 6 0 7 0 0
0 2 0 3 0 4 0 5 0 6 0 7 0
1 0 2 0 3 0 4 0 5 0 6 0 7
With hourglass(7, filler_char=' ') it prints:
1 2 3 4 5 6 7
2 3 4 5 6 7
3 4 5 6 7
4 5 6 7
5 6 7
6 7
7
6 7
5 6 7
4 5 6 7
3 4 5 6 7
2 3 4 5 6 7
1 2 3 4 5 6 7
for k in range(i,inputString+1):
print(k,"0",end=" ")
print()
This section is your problem. Once it prints the final character (the 3 in your case), the loop tacks on another '0' and a whitespace and calls it a day. If you want whitespace instead of zeros this isn't a problem since they are visually indistinguishable, but an absence of any character obviously doesn't look the same as a '0' character. You can verify this by highlighting the sample output from the geeksforgeeks article in your browser; the leading whitespaces are there but the trailing whitespaces don't exist - after the 8 in each row is simply a whitespace then a newline character.

Incrementing add under condition in pandas

For the following pandas dataframe
servo_in_position second_servo_in_position Expected output
0 0 1 0
1 0 1 0
2 1 2 1
3 0 3 0
4 1 4 2
5 1 4 2
6 0 5 0
7 0 5 0
8 1 6 3
9 0 7 0
10 1 8 4
11 0 9 0
12 1 10 5
13 1 10 5
14 1 10 5
15 0 11 0
16 0 11 0
17 0 11 0
18 1 12 6
19 1 12 6
20 0 13 0
21 0 13 0
22 0 13 0
I want to increment the column "Expected output" only if "servo_in_position" changes from 0 to 1. I want also to assume "Expected output" to be 0 (null) if "servo_in_position" equals to 0.
I tried
input_data['second_servo_in_position']=(input_data.servo_in_position.diff()!=0).cumsum()
but it gives output as in "second_servo_in_position" column, which is not what I wanted.
After that I would like to group and calculate mean using:
print("Mean=\n\n",input_data.groupby('second_servo_in_position').mean())
Using cumsum and arithmetic.
u = df['servo_in_position']
(u.eq(1) & u.shift().ne(1)).cumsum() * u
0 0
1 0
2 1
3 0
4 2
5 2
6 0
7 0
8 3
9 0
10 4
11 0
12 5
13 5
14 5
15 0
16 0
17 0
18 6
19 6
20 0
21 0
22 0
Name: servo_in_position, dtype: int64
Use cumsum and mask:
df['E_output'] = df['servo_in_position'].diff().eq(1).cumsum()\
.mask(df['servo_in_position'] == 0, 0)
df['servo_in_position'].diff().fillna(df['servo_in_position']).eq(1).cumsum()\
.mask(df['servo_in_position'] == 0, 0)
Output:
servo_in_position second_servo_in_position Expected output E_output
0 0 1 0 0
1 0 1 0 0
2 1 2 1 1
3 0 3 0 0
4 1 4 2 2
5 1 4 2 2
6 0 5 0 0
7 0 5 0 0
8 1 6 3 3
9 0 7 0 0
10 1 8 4 4
11 0 9 0 0
12 1 10 5 5
13 1 10 5 5
14 1 10 5 5
15 0 11 0 0
16 0 11 0 0
17 0 11 0 0
18 1 12 6 6
19 1 12 6 6
20 0 13 0 0
21 0 13 0 0
22 0 13 0 0
Update for first position equal to 1.
df['servo_in_position'].diff().fillna(df['servo_in_position']).eq(1).cumsum()\
.mask(df['servo_in_position'] == 0, 0)
Try np.where:
df['Expected_output'] = np.where(df.servo_in_position.eq(1),
df.servo_in_position.diff().eq(1).cumsum(),
0)
That is cumsum and mul
df.servo_in_position.diff().eq(1).cumsum().mul(df.servo_in_position.eq(1),axis=0)
Fast with Numba
from numba import njit
#njit
def f(u):
out = np.zeros(len(u), np.int64)
a = out[0] = u[0]
for i in range(1, len(u)):
if u[i] == 1:
if u[i - 1] == 0:
a += 1
out[i] = a
return out
f(df.servo_in_position.to_numpy())
array([0, 0, 1, 0, 2, 2, 0, 0, 3, 0, 4, 0, 5, 5, 5, 0, 0, 0, 6, 6, 0, 0, 0])

Splitting pandas dataframe based on value

I would like to split pandas dataframe to groups in order to process each group separately. My 'value.csv' file contains the following numbers
num tID y x height width
2 0 0 0 1 16
2 1 1 0 1 16
5 0 1 0 1 16
5 1 0 0 1 8
5 2 0 8 1 8
6 0 0 0 1 16
6 1 1 0 1 8
6 2 1 8 1 8
2 0 0 0 1 16
2 1 1 0 1 16
5 0 1 0 1 16
5 1 0 0 1 8
5 2 0 8 1 8
6 0 0 0 1 16
6 1 1 0 1 8
6 2 1 8 1 8
I would like to split the data based on the starting value of 0 at the tID column like that for the first 4 seperation.
First:
2 0 0 0 1 16
2 1 1 0 1 16
Second:
5 0 1 0 1 16
5 1 0 0 1 8
5 2 0 8 1 8
Third:
6 0 0 0 1 16
6 1 1 0 1 8
6 2 1 8 1 8
Fourth:
2 0 0 0 1 16
2 1 1 0 1 16
For this, I tried to split it using if but no success, any efficient ideas?
import pandas as pd
statQuality = 'value.csv'
df = pd.read_csv(statQuality, names=['num','tID','y','x','height','width'])
df2 = df.copy()
df2.drop(['num'], axis=1, inplace=True)
x = []
for index, row in df2.iterrows():
if row['tID'] == 0:
x = []
x.append(row)
print(x)
else:
x.append(row)
Use:
#create groups by consecutive values
s = df['num'].ne(df['num'].shift()).cumsum()
#create helper count Series for duplicated groups like `2_0`, `2_1`...
g = s.groupby(df['num']).transform(lambda x: x.factorize()[0])
#dictionary of DataFrames
d = {'{}_{}'.format(i,j): v.drop('num', axis=1) for (i, j), v in df.groupby(['num', g])}
print (d)
{'2_0': tID y x height width
0 0 0 0 1 16
1 1 1 0 1 16, '2_1': tID y x height width
8 0 0 0 1 16
9 1 1 0 1 16, '5_0': tID y x height width
2 0 1 0 1 16
3 1 0 0 1 8
4 2 0 8 1 8, '5_1': tID y x height width
10 0 1 0 1 16
11 1 0 0 1 8
12 2 0 8 1 8, '6_0': tID y x height width
5 0 0 0 1 16
6 1 1 0 1 8
7 2 1 8 1 8, '6_1': tID y x height width
13 0 0 0 1 16
14 1 1 0 1 8
15 2 1 8 1 8}

How to add another condition to Sudoku puzzle

I have just start coding with python since fall. So i am not a professional python coder.
I have started to code a Sudoku program. And fortunately at last I could have come up with this code:
def isValid(num, x, y):
for i in range(9):
if board[i][y] == num:
return False
if board[x][i] == num:
return False
row = x - x % 3
col = y - y % 3
for i in range(3):
for j in range(3):
if board[i + row][j + col] == num:
return False
return True
def solve(remaining):
if remaining == 0:
return True
for i in range(9):
for j in range(9):
if board[i][j] != 0:
continue
for num in range(1, 10):
if isValid(num, i, j):
board[i][j] = num
if solve(remaining - 1):
return True
board[i][j] = 0
return False
return False
def pp():
for i in range(9):
for j in range(9):
print(board[i][j], end=" ")
print()
print()
board = []
remaining = 0
for i in range(9):
a=input()
a=a.split()
a = list(map(int, a))
for j in a:
if j == 0:
remaining += 1
board.append(a)
solve(remaining)
pp()
For instance I give such an input to it:
0 0 0 0 0 0 0 1 0
0 0 2 0 0 0 0 3 4
0 0 0 0 5 1 0 0 0
0 0 0 0 0 6 5 0 0
0 7 0 3 0 0 0 8 0
0 0 3 0 0 0 0 0 0
0 0 0 0 8 0 0 0 0
5 8 0 0 0 0 9 0 0
6 9 0 0 0 0 0 0 0
And this is my output:
7 4 9 2 3 8 6 1 5
1 5 2 6 9 7 8 3 4
8 3 6 4 5 1 2 7 9
2 1 8 9 7 6 5 4 3
9 7 5 3 2 4 1 8 6
4 6 3 8 1 5 7 9 2
3 2 1 5 8 9 4 6 7
5 8 4 7 6 3 9 2 1
6 9 7 1 4 2 3 5 8
Now I intend to add a new condition to this Sudoku which is can do this process for 4 more 3*3 boxes in the board like this (which is named Hyper-Sudoku):
That for my puzzle it returns:
9 4 6 8 3 2 7 1 5
1 5 2 6 9 7 8 3 4
7 3 8 4 5 1 2 9 6
8 1 9 7 2 6 5 4 3
4 7 5 3 1 9 6 8 2
2 6 3 5 4 8 1 7 9
3 2 7 9 8 5 4 6 1
5 8 4 1 6 3 9 2 7
6 9 1 2 7 4 3 5 8
Is there any way to add this option to my Sudoku or not, I have to change my whole algorithm?
Thanks for your answers.
I think your program looks great. Since you separated your isValid and solve functions it makes adding the change easier. All you will need to is modify the isValid function.
def isValid(num, x, y):
# row and column check
for i in range(9):
if board[i][y] == num:
return False
if board[x][i] == num:
return False
# 3x3 tile check
row = x - x % 3
col = y - y % 3
for i in range(3):
for j in range(3):
if board[i + row][j + col] == num:
return False
# Hypersudoku check
if x not in [0, 4, 8] and y not in [0, 4, 8]:
row = 1 if x < 4 else 5
col = 1 if y < 4 else 5
for i in range(3):
for j in range(3):
if board[i + row][j + col] == num:
return False
return True

Categories

Resources