Optimization of checking on conditions in a 3d array

I have an example of a python code snippet. I need to check all the numbers from the map_spectrum array for 5 conditions, then put the new value in another array according to them. How can this be done in a more optimized version than in python code ?

x = y = np.arange(0.0, 1.0, 0.1)
map_spectrum = np.ones( (len(x), len(y), 6) )
map_color = np.ones( ( len(x), len(y) ) )

for ix, xv in enumerate(x):
    for iy, yv in enumerate(y):
            if map_spectrum[ix, iy, 0] > 0 and map_spectrum[ix, iy, 1] > 0 and map_spectrum[ix, iy, 2] == 0 and map_spectrum[ix, iy, 3:] < 0 :
                        map_color[ix, iy] = 1

In the real case, this array has a size of 101x101x6, that is, conditionally there are 10201 cells containing 6 values.
All the cases of conditions in a short form:

First case +, +, 0, -, -, -
Second case +, 0, -, - ,- ,-
Third case 0, 0, -, -, -, -
Four case 0, -, -, -
Another

In addition, how to take into account machine zero when checking conditions.
Example real values from array
image

After creating a new array, it will be used as colors in heatmap that is

heatmap(x, y, map_color)

I tried to cycle through all the values and check them for 5 conditions, but it takes quite a long time

this loop will run pretty fast in Julia, have you tried?

With a large array, this may take some time, also I would like to avoid using a loop or at least 5 conditions in a row in a loop. but even if we leave everything in this form, there remains the problem of how to check whether an infinitesimal value is really zero.

how else do you want to do this?

use a cutoff

julia> isapprox(1e-15, 0.0; atol=1e-16)
false

julia> isapprox(1e-17, 0.0; atol=1e-16)
true
1 Like

I’m thinking of using the equivalent switch statement from c++, but Julia doesn’t have it therefore, apparently there remains only the option of placing 5 conditions in the function.

The value can have, for example, 1 e4 or 1e-6 or 1.0762649529273773e-6 and this should be considered a machine zero
I can only specify which precision is considered zero?

atol is the absolute tolerance

you have five conditions ANDed together, how are you gonna use switch?

try using ternary operator in this way

First case +, +, 0, -, -, -
Second case +, 0, -, - ,- ,-
Third case 0, 0, -, -, -, -
Four case 0, -, -, -
Another

ms0>0 && ms1>0 && ms2==0 && ms3<0   ? mp = "first" :
ms0>0 && ms1==0                     ? mp = "second" :
ms0==0 && ms1==0                    ? mp = "third" :
ms0==0                              ? mp = "four" :
                                      mp = "another"
1 Like

Thank you, i read it and in general I understood how to use it except for one moment. I have not found an example in which the result would be written to a new variable and not the current one

I’m not sure what your doubt is. If you are referring to the variable mp = 1, mp = 2 …, in its place you can put any expression with any variable

I understanded, sorry. I checked this with my code and it’s work.
It remains to check isapprox on my data

isaprox don’t work with number 1.9184694551117396e-5

isapprox(1.9184694551117396e-5, 0.0; atol = 1e-8)

how to fix it or I don’t fully understand something

your tolerance is smaller than the difference, make the tolerance larger