Reputation: 35
I need to convert the block of code that's shown below to Python. I created two arrays named u
and v
seperately and put them in a for loop in the range 0 to M-1 and I know find
works similar to if condition. I have a problem since both idx
and u
are arrays.
MATLAB code is this:
u = 0:(M-1);
v = 0:(N-1);
idx = find(u > M/2);
u(idx) = u(idx) - M; #I have a problem here
idy = find(v > N/2);
v(idy) = v(idy) - N;
Basically what I have done in Python until I got to this problematic line is:
input_image = Image.open('./....image....')
input_image=np.array(input_image)
M,N = input_image.shape[0],input_image.shape[1]
FT_img = fftpack.fftshift(fftpack.fft2(input_image))
# Assign the order value
n = 2; # one can change this value accordingly
# Assign Cut-off Frequency
D0 = 60; # one can change this value accordingly
# Designing filter
u=[]
v=[]
for i in range(M-1):
u.append(i)
for i in range(N-1):
v.append(i)
Upvotes: 1
Views: 792
Reputation: 4636
u = 0:(M-1)
do in Matlab and how can we do the same thing in Python?The following is one excerpt from your original Matlab code:
% BEGIN MATLAB %
u = 0:(M-1);
% END MATLAB %
What does the code do?
Suppose that M = 7
. Then the Matlab code simplifies:
u = 0:6;
The result is an array u
beginning at 0
and ending at 6
:
u = [0 1 2 3 4 5 6]
Essentially, you are initializing an array of consecutive integers.
There are various ways to accomplish something similar in Python:
# Begin Python
M = 7
u = list(range(0, M))
# End python
Note that range(0, 7)
looks like [0, ..., 5, 6]
, not [0, ..., 6, 7]
Python's range
function automatically subtracts 1
from the upper limit
If you really are doing Matlab-type stuff, then numpy
is the library you want to use in Python:
import numpy as np
u = np.array(range(0, 7))
Note that Matlab indexing begins at 1
.
Python indexing begins at 0
.
ARRAY = ["red", "blue", "white", "green"]
+--------------+-------+--------+---------+---------+
| ARRAY | "red" | "blue" | "white" | "green" |
+--------------+-------+--------+---------+---------+
| PYTHON INDEX | 0 | 1 | 2 | 3 |
| MATLAB INDEX | 1 | 2 | 3 | 4 |
+--------------+-------+--------+---------+---------+
find
functionfind
from Matlab into EnglishConsider the find
function from Matlab:
idx = find(u > M/2); % this is matlab-code
The function-call find(u)
will search the entire array u
for anything strictly larger than M/2
. find(u)
will then return a list of all indices for things larger than M/2
Consider the following example of the find
function:
u = [98 00 00 87 49 50 51 00 85];
% 1 2 3 4 5 6 7 8 9 .....ARRAY INDICIES
idx = find(u > 50);
disp(idx)
% displays .... 1 4 7 9
find(u > 50)
will find the indices of every element of u
greater than or equal to 51
Consider the code u(idx) = 22;
We have the following results:
+---------------------+------+-----+-----+------+-----+-----+------+-----+------+
| MATLAB INDICIES | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
+---------------------+------+-----+-----+------+-----+-----+------+-----+------+
| print(u) | 99 | 00 | 00 | 99 | 49 | 50 | 51 | 00 | 99 |
+---------------------+------+-----+-----+------+-----+-----+------+-----+------+
| % u > 50? | %yes | %no | %no | %yes | %no | %no | %yes | %no | %yes |
+---------------------+------+-----+-----+------+-----+-----+------+-----+------+
| idx = find(u > 50); | | | | | | | | | |
| u(idx) = 22; | | | | | | | | | |
+---------------------+------+-----+-----+------+-----+-----+------+-----+------+
| print(u) | 22 | 0 | 0 | 22 | 49 | 50 | 22 | 0 | 22 |
+---------------------+------+-----+-----+------+-----+-----+------+-----+------+
Everything inside of array u
greater than or equal to 51
was replaced with 22
find
from English to PythonSuppose that you have an array u
in Python.
You want to replace every integer greater than or equal to 51
with 22
You can do that in Python using the numpy
library:
# This is Python (not matlab)
import numpy as np
u = [98 00 00 87 49 50 51 00 85];
u = np.array(u)
u[u > 50] = 22
# THIS IS PYTHON CODE (not matlab)
Note that u[u > 50] = 22
is the same as the following:
# THIS IS PYTHON CODE (not matlab)
indicies = type(u).__gt__(u, 50)
u.__setitem__(indicies, 22)
# THIS IS PYTHON CODE (not matlab)
find
from Matlab to PythonIf you translate part of your original code from Matlab to Python it would look like the following:
MATLAB INPUT:
M = 7
u = 0:(M-1);
idx = find(u > M/2);
u(idx) = u(idx) - M;
PYTHON OUTPUT:
# THIS IS PYTHON CODE (not matlab)
import numpy as np
M = 7
u = np.array(range(0, M))
idx = u > M/2
u[idx] = u[idx] - M
# THIS IS PYTHON CODE (not matlab)
In the beginning of the post I explained what a few individual pieces of your Matlab code do.
Now, let us translate the entire Matlab script into English and Math.
*** SOMETHING SIMILAIR TO YOUR ORIGINAL/OLD MATLAB IS BELOW ***
function u = GenerateArray(M)
u = 0:(M-1);
idx = find(u > M/2);
u(idx) = u(idx) - M;
end
M = 7;
u = GenerateArray(M);
N = 9;
v = GenerateArray(N);
*** THE BEHAVIOR AS A TABLE***
I think that the Matlab code is easier to understand as a table, than as code:
+--------------+---------------------------+
| WHOLE NUMBER | ARRAY |
| `M` | `u` |
+--------------+---------------------------+
| 4 | 0 1 2 -1 |
| 5 | 0 1 2 -2 -1 |
| 6 | 0 1 2 3 -2 -1 |
| 7 | 0 1 2 3 -3 -2 -1 |
+--------------+---------------------------+
For M > 7
:
[0, 1 , 2, 3, [...], floor(M/2)]
lang-none [(-1)*(x-0), (-1)*(x-1), (-1)*(x-2), [...], -3, -2, -1]
where x equals floor((M-1)/2)
The following Python script has the same output as the Matlab script:
import numpy as np
import itertools as itts
def generate_data(array_size : int) -> type(np.array(range(0, 1))):
"""
+--------------+---------------------------+
| INPUT | OUTPUT |
+--------------+---------------------------+
| 4 | 0 1 2 -1 |
| 5 | 0 1 2 -2 -1 |
| 6 | 0 1 2 3 -2 -1 |
| 7 | 0 1 2 3 -3 -2 -1 |
+--------------+---------------------------+
* the left side of the array:
starts at:
zero
ends at:
floor(M/2)
counts by:
+1
looks like:
[0, 1 , 2, 3, [...], floor(M/2)]
* the right side of the array...
starts at
(-1) * floor((M-1)/2)
ends at:
-1
counts by:
-1
looks like:
[
(-1) * floor((M-1)/2),
(-1) * (floor((M-1)/2) - 1),
(-1) * (floor((M-1)/2) - 2),
[...],
-3,
-2,
-1
]
"""
# clean_input = int(dirty_input)
n = int(array_size)
# make the first element of the left side of the array be zero.
# left_side_first = 0
lsf = 0
# left_side_last = clean_input // 2
lsl = n // 2
# left_side_iterator = range(left_side_first, 1 + left_side_last)
lsit = range(lsf, 1 + lsl)
# `list` stands for "left side iterator"
right_side_first = (-1) * ((n - 1) // 2)
right_side_last = -1
right_side_iterator = range(right_side_first, 1 + right_side_last)
# merged_iterator = chain(left_side_iterator, right_side_iterator)
merged_iterator = itts.chain(lsit, right_side_iterator)
output = np.array(list(merged_iterator))
# We convert the iterator to a `list` because the following
# direct use of the iterator does not work:
#
# output = np.array(merged_iterator)
return output
We can call the Python function like so:
arr = generate_data(14)
print(arr)
The output for input 14
is shown below:
[ 0 1 2 3 4 5 6 7 -6 -5 -4 -3 -2 -1]
Upvotes: 3
Reputation: 60695
Your MATLAB code
u = 0:(M-1);
idx = find(u > M/2);
u(idx) = u(idx) - M;
can be more efficiently implemented by leaving out find
:
u = 0:(M-1);
idx = u > M/2;
u(idx) = u(idx) - M;
This form is trivially translatable to Python with NumPy:
u = np.arange(0, M)
idx = u > M/2
u[idx] = u[idx] - M
Upvotes: 1