How to get the mean of specific values from an nd.array region? - arrays

Given an ndarray:
np.array(
(
(1, 2, 3, 3, 2),
(4, 5, 4, 3, 2),
(1, 1, 1, 1, 1),
(0, 0, 0, 0, 0),
(0, 2, 3, 4, 0),
)
)
extract the mean of the values bounded by a rectangle with coordinates: (1, 1), (3, 1), (1, 3), (3, 3).
The extracted region of the array would be:
5, 4, 3,
1, 1, 1,
0, 0, 0,
And the mean would be ~1.666666667

import numpy as np
arr = np.array(
(
(1, 2, 3, 3, 2),
(4, 5, 4, 3, 2),
(1, 1, 1, 1, 1),
(0, 0, 0, 0, 0),
(0, 2, 3, 4, 0),
)
)
mean = arr[1:4, 1:4].mean()

Related

How to convert RBG data into a Image

I'm doing a easy cybersecurity challenge where I'm given a data file with only RBG codes like the following ones:
[(0, 0, 2), (0, 0, 2), (0, 0, 2), (0, 0, 2), (0, 0, 2), (0, 0, 2), (0, 0, 2), (0, 0, 2), (0, 0, 2), (1, 1, 3), (1, 1, 3), (1, 1, 3), (0, 0, 2), (0, 0, 2), (0, 0, 2), (1, 1, 3), (0, 0, 2), (0, 0, 2), (1, 1, 3), (1, 1, 3), (1, 1, 3), (1, 1, 3), (0, 0, 2), (0, 0, 2), (1, 1, 3)]
As you may wonder, the file is much wider and longer and I don't know how I should convert all this RBG data into an image. I tried using a python script in a Lubuntu1204 but it still gave me some errors and I didnt get the image I was looking for.
Thanks for the help in advance!

Map Tuples to Array Swift

I have an array of tuples:
[(0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1)]
What is the best way to convert this to just a single array of [0, 1, 0, 1.....] ?
I have tried
let newArray = tupleArray.map{$0.0, $0.1}
but it doesn't work and says consecutive statements must be separated by ;. There must be some clever way to reduce them.
You need to add both elements to an array in the closure and you also need to use flatMap instead of map to flatten out the nested array that map would produce.
let arrayOfTuples = [(0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1)]
let flattenedArray = arrayOfTuples.flatMap{ [$0.0, $0.1] }
This will be your answer :
let arrTouple = [(0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1)]
let arr = arrTouple.flatMap{ [$0, $1] }
print(arr) // [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
Simply use map(_:) and flatMap(_:) to flatten the tuples array,
let tuples = [(0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1)]
let arr = tuples.map({ [$0.0, $0.1] }).flatMap({ $0 })
Output:
[0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1]

Iterate through multiple variables (or whole matrix) in Julia

I have a 5 dimensional array want to do a calculation for each field and depending on the result fill each field either with 'true' or 'false'. Now I am wondering if there is a fast way of doing so without using 5 'nested' loops.
Thanks for your help
Edit:
Sorry that the question wasn't clear. I need to do calculations with 5 different variables and I have check each possible combination.
My current approach is this:
while i<10
while j<10
while k < 10
while l<10
while m <10
#some calculation which returns true or false
A[i,j,k,l,m]=f(i, j, k, l, m);
m+=1;
end
l+=1;
end
k +=1;
end
j+=1;
end
i+=1;
end
where A is my array. Now I am wondering if there is a more efficient way of doing this.
Sorry, I hope it is more clarified now.
You can use CartesianIndices function for example like this:
julia> x = Array{Tuple}(undef, 2,2,2,2,2);
julia> for idx in CartesianIndices(x)
x[idx] = Tuple(idx)
end
julia> x
2×2×2×2×2 Array{Tuple,5}:
[:, :, 1, 1, 1] =
(1, 1, 1, 1, 1) (1, 2, 1, 1, 1)
(2, 1, 1, 1, 1) (2, 2, 1, 1, 1)
[:, :, 2, 1, 1] =
(1, 1, 2, 1, 1) (1, 2, 2, 1, 1)
(2, 1, 2, 1, 1) (2, 2, 2, 1, 1)
[:, :, 1, 2, 1] =
(1, 1, 1, 2, 1) (1, 2, 1, 2, 1)
(2, 1, 1, 2, 1) (2, 2, 1, 2, 1)
[:, :, 2, 2, 1] =
(1, 1, 2, 2, 1) (1, 2, 2, 2, 1)
(2, 1, 2, 2, 1) (2, 2, 2, 2, 1)
[:, :, 1, 1, 2] =
(1, 1, 1, 1, 2) (1, 2, 1, 1, 2)
(2, 1, 1, 1, 2) (2, 2, 1, 1, 2)
[:, :, 2, 1, 2] =
(1, 1, 2, 1, 2) (1, 2, 2, 1, 2)
(2, 1, 2, 1, 2) (2, 2, 2, 1, 2)
[:, :, 1, 2, 2] =
(1, 1, 1, 2, 2) (1, 2, 1, 2, 2)
(2, 1, 1, 2, 2) (2, 2, 1, 2, 2)
[:, :, 2, 2, 2] =
(1, 1, 2, 2, 2) (1, 2, 2, 2, 2)
(2, 1, 2, 2, 2) (2, 2, 2, 2, 2)
The code stores in an entry `x[a,b,c,d,e]` a tuple `(a,b,c,d,e)`.
You can do the same kind of operations as you'd do on a 1-Dimensional matrix.
julia> A = rand(4,4,4,4,4);^C
julia> for (i, v) in enumerate(A)
if v > 0.5
A[i] = 0
end
end
Also, somthing like:
julia>map!(x->x>.5, A, A)
Also if the original Array is of some type other than Bool I'd suggest you use a different matrix to assign the result values for type stability.

Finding recurrence relation and complexity

Based on the number of operations, finding out the recurrence relation!
a = N;
var = 0;
while (a > 1)
{
var = var + a;
num = 2 * var;
a = a / 2;
}
I think that the the recurrence relaton that will be formed is: (Assignment operations are to be not counted)
T(n)= (from a=1 to N)Σ(3)
Am I right??
Now using this recurrence relation, how to find its complexity.
What you want to do is find how many times this operation is called, so consider this: after each call a is divided by 2, so if M = N/2 then T(M) = T(N) - 1.
Now, each iteration of this loop divides N again so you get the following:
T(N) = T(N/2) + 1 = ... = k + T(N/(2^k))
The stop condition is this: a>1 so you need to check when N/(2^k) <= 1
N/2^k = 1 -> log (n) = k
So T(N) = log(n) + T(1) = log(n)
This is the answer in 'big O' notation.
Empirical approach:
First reduce the "educational noise" from the code by simplifying it and add an iteration counter (c). Then look at the result (N,count) and after a while you see, that 2 ^ count = N for all N in [1,2,4,8,16,..].
So the complexity Compl(loop) = O(log_2(N)).
let rec loop a c =
match a with
| x when x > 1 ->
let a1 = a / 2
loop a1 (c+1)
| _ -> (a,c)
// after staring at the result of the computation we came up with this theory:
let theory n = int (System.Math.Log10(float n) / System.Math.Log10(2.0))
[1..64]
|> List.map (fun a -> a,loop a 0, theory a)
|> List.map (fun (a0,(a,c),aa) -> a0,c,aa)
Data:
[(1, 0, 0); (2, 1, 1); (3, 1, 1); (4, 2, 2); (5, 2, 2); (6, 2, 2); (7, 2, 2);
(8, 3, 3); (9, 3, 3); (10, 3, 3); (11, 3, 3); (12, 3, 3); (13, 3, 3);
(14, 3, 3); (15, 3, 3); (16, 4, 4); (17, 4, 4); (18, 4, 4); (19, 4, 4);
(20, 4, 4); (21, 4, 4); (22, 4, 4); (23, 4, 4); (24, 4, 4); (25, 4, 4);
(26, 4, 4); (27, 4, 4); (28, 4, 4); (29, 4, 4); (30, 4, 4); (31, 4, 4);
(32, 5, 5); (33, 5, 5); (34, 5, 5); (35, 5, 5); (36, 5, 5); (37, 5, 5);
(38, 5, 5); (39, 5, 5); (40, 5, 5); (41, 5, 5); (42, 5, 5); (43, 5, 5);
(44, 5, 5); (45, 5, 5); (46, 5, 5); (47, 5, 5); (48, 5, 5); (49, 5, 5);
(50, 5, 5); (51, 5, 5); (52, 5, 5); (53, 5, 5); (54, 5, 5); (55, 5, 5);
(56, 5, 5); (57, 5, 5); (58, 5, 5); (59, 5, 5); (60, 5, 5); (61, 5, 5);
(62, 5, 5); (63, 5, 5); (64, 6, 6)]
The recurrence relation is:
T(1) = a
T(n) = b + T(n/2)
The first part comes from the case where the loop variable equals 1, in which case only the comparison at the top of the loop executes. The second line comes from the constant amount of work done in the loop body, b, plus the time to execute the loop with the updated loop variable value.
The first few terms are:
n T
1 a
2 a + b
4 a + 2b
8 a + 3b
Based on this we can guess the general form:
T(n) = a + b log n
Proving that is left as an exercise; but you can just plug it in to the recurrence relation to see that it satisfies the requirements.
The asymptotic complexity is logarithmic.

Array manipulation in Fortran

I have two arrays fListU and fListD both of which contain 4-tuples. Specifically:
fListU = [(2, 1, 1, 0), (2, 5, 5, 0), (5, 4, 10, 0), (6, 1, 5, 0), (6, 5, 7, 0)]
fListD = [(1, 4, 0, 4), (3, 4, 0, 4), (5, 4, 0, 6)]
Now I want to put together these into one array, with the condition that when the first two items of the tuples are equal, then the third and fourth items of two lists should be added. In this case, the result I am looking for is
fList = [(2, 1, 1, 0), (2, 5, 5, 0), (5, 4, 10, 6), (6, 1, 5, 0),
(6, 5, 7, 0), (1, 4, 0, 4), (3, 4, 0, 4)]
where (5, 4, 10, 0) and (5, 4, 0, 6) are combined to (5, 4, 10, 6).
This is what I tried.
ALLOCATE (fList((n-1)**2,4))
fList = 0
p = 1 ! p signifies the position in fList.
DO k = 1, ((n-1)**2), 1 ! k is the index for fListD
DO l = 1, ((n-1)**2), 1 ! l is the index for fListU
IF ( ALL (fListU(l,1:2) == fListD(k,1:2)) ) THEN
fList(p,1:2) = fListU(l,1:2)
fList(p,3) = fListU(l,3)
fList(p,4) = fListD(k,4)
ELSE
fList(p,:) = fListU(l,:)
p = p+1
fList(p,:) = fListD(k,:)
p = p+1
END IF
END DO
END DO
This is not producing what I want. What would be the problem?
I'm not sure how you are reading in fListU and fListD. One thing that you need to realise is that in Fortran (other than most other programming languages), the first index of a multi-dimensional array is the fastest changing. That's why the way you read the data in is so important: If you read the data in sequentially, or use reshape, then the second element you read in will be in position (2, 1), not (1, 2) as you might expect.
So I strongly suggest to have the shape of fListU as (4, 5), not (5, 4), and consequently address the first two elements of a tuple as flist(1:2, p).
Here's a possible solution that knows the lengths of the two input arrays.
The output will still contain another line of all zeros, because I haven't programmed it to get the size of the output array right (instead it just uses the sum of the sizes of the input arrays).
program Combine_List_Simple
implicit none
integer, dimension(:, :), allocatable :: fListU, fListD, fList
integer :: u_size, d_size
integer :: u_index, d_index, f_index
u_size = 5
allocate(fListU(4, u_size))
fListU = reshape((/2, 1, 1, 0, 2, 5, 5, 0, 5, 4, 10, 0, &
6, 1, 5, 0, 6, 5, 7, 0/), (/4, u_size/))
d_size = 3
allocate(fListD(4, d_size))
fListD = reshape((/1, 4, 0, 4, 3, 4, 0, 4, 5, 4, 0, 6/), &
(/4, d_size/))
allocate(fList(4, u_size + d_size))
flist(:, 1:u_size) = fListU(:, :)
flist(:, u_size+1:) = 0
f_index = u_size+1
d_loop : do d_index = 1, d_size
do u_index = 1, u_size
if (all(fListD(1:2, d_index) == fList(1:2, u_index))) then
fList(4, u_index) = fListD(4, d_index)
cycle d_loop
end if
end do
fList(:, f_index) = fListD(:, d_index)
f_index = f_index+1
end do d_loop
write(*, '(4I4)') fList
end program Combine_List_Simple
This code also assumes that the 4th element of all tuples in fListU and the 3rd element of all tuples in fListD is zero. But your code seems to assume that as well. Also it assumes that the combination of 1st and 2nd elements of the tuples are unique in each of the input arrays.
First, I completely copy the contents of fListU into fList. Then I loop over fListD, and compare it to the first entries in fList, because that's where the contents of fListU are. If it finds a match, it updates only the 4th element of the tuple, and then cycles the loop of the fListD array.
Only if it doesn't find a match will it reach the end of the inner loop, and then append the tuple to fList.

Resources