Author Topic: Pixel Math If (Case or Switch statement)  (Read 683 times)

Offline ngc1535

  • PixInsight Old Hand
  • ****
  • Posts: 326
Pixel Math If (Case or Switch statement)
« on: 2019 February 20 12:14:04 »
Hi,

Currently iif is implemented as a "hard" if/else statement in that if not one thing- the other thing must occur.

Please don't ask me why...but I was trying to construct an image that was a single row of (lets say 10) pixels.
And I wanted to assign them each a value. I might naively (ha ha..this is exactly what I did) do something like:

iif( x()==0, 0.020749760758206493, 0);
iif( x()==1, 0.02083269071095121, 0);
iif( x()==2, 0.020591074008640423, 0);
iif( x()==3, 0.020587894424854085, 0);
iif( x()==4, 0.02125898032182231, 0)
...

But for each pixel- as it runs through each condition- the else part is always executed (in this case the "0'). Changing this to $T doesn't help.
I really need a soft "iif" that only does something if the statement is True...but is silent (does nothing) if false.
Is there a way to do this?

Basically I am hoping for a Case/Switch statement. I can't see there is a means to do it now... perhaps there is a reason?

Thanks in advance for any help. I know it is kinda a weird question.

-adam

Offline Juan Conejero

  • PTeam Member
  • PixInsight Jedi Grand Master
  • ********
  • Posts: 7111
    • http://pixinsight.com/
Re: Pixel Math If (Case or Switch statement)
« Reply #1 on: 2019 February 20 12:45:19 »
Hi Adam,

Semantically, the solution to this problem should be of the form:

iif( <condition>, <if-true-expression>, $T )

where $T playing the role of <if-false-expression> leaves unmodified all pixels for which <condition> is false.

Indeed, you have identified one of the issues that needs an urgent improvement in PixelMath: the fact that both expressions, <if-true-expression> and <if-false-expression>, are always evaluated, irrespective of <condition>. This is obviously a performance issue. This happens because the current PixelMath interpreter uses a relatively simple stack-based implementation of an expression tree, where iif() is handled just as a function with three parameters, while it is not a function but a flow control structure with the appearance of a function (heck, I wrote this almost 16 years ago!). This (now naive) implementation should be changed ASAP to something more efficient, such as a specialized bytecode virtual machine. This is in the to-do list for sure.

Having said that, you might prefer the JavaScript runtime for what you are trying to do. This is why PixInsight is a scriptable platform, after all: to help solve unexpected, unexpectedly complex problems :)

Juan Conejero
PixInsight Development Team
http://pixinsight.com/

Offline ngc1535

  • PixInsight Old Hand
  • ****
  • Posts: 326
Re: Pixel Math If (Case or Switch statement)
« Reply #2 on: 2019 February 20 13:11:40 »
Thank you Juan,

Yes, I understand about $T and that is what I originally did...but if you think about *that* for a moment when you create an image and then keep applying to understand what is going on... it gets confusing ! lol

Anyway, I am comforted to know I didn't miss something and also that it could become a reality in the future.
PixelMath is really fantastic- Thank you for creating it...I was going to use this unexpected construct as a teaching example...
I have just barely started to program in Python. I don't think my brain can take another language.

-Adam

Hi Adam,

Semantically, the solution to this problem should be of the form:

iif( <condition>, <if-true-expression>, $T )

where $T playing the role of <if-false-expression> leaves unmodified all pixels for which <condition> is false.

Indeed, you have identified one of the issues that needs an urgent improvement in PixelMath: the fact that both expressions, <if-true-expression> and <if-false-expression>, are always evaluated, irrespective of <condition>. This is obviously a performance issue. This happens because the current PixelMath interpreter uses a relatively simple stack-based implementation of an expression tree, where iif() is handled just as a function with three parameters, while it is not a function but a flow control structure with the appearance of a function (heck, I wrote this almost 16 years ago!). This (now naive) implementation should be changed ASAP to something more efficient, such as a specialized bytecode virtual machine. This is in the to-do list for sure.

Having said that, you might prefer the JavaScript runtime for what you are trying to do. This is why PixInsight is a scriptable platform, after all: to help solve unexpected, unexpectedly complex problems :)

Offline RickS

  • PTeam Member
  • PixInsight Jedi
  • *****
  • Posts: 1298
Re: Pixel Math If (Case or Switch statement)
« Reply #3 on: 2019 February 20 16:49:21 »
There's always the option of nesting your iif expressions, Adam.  It can get unwieldy and you need to be careful matching the parentheses, but it might be easier than learning JavaScript.

iif(x()==0, 0.020749760758206493, iif(x()==1, 0.02083269071095121, iif(x()==2, 0.020591074008640423, ...

Cheers,
Rick.

Offline ngc1535

  • PixInsight Old Hand
  • ****
  • Posts: 326
Re: Pixel Math If (Case or Switch statement)
« Reply #4 on: 2019 February 20 19:32:52 »
I did try that... the last statement is still a killer for this logic??
I could be wrong. (Did you try?)
-adam

Offline sharkmelley

  • PTeam Member
  • PixInsight Addict
  • ***
  • Posts: 241
    • Mark Shelley Astrophotography
Re: Pixel Math If (Case or Switch statement)
« Reply #5 on: 2019 February 20 23:11:34 »

Here's another approach I've often used:

val=0;
val+=iif( x()==0, 0.020749760758206493, 0);
val+=iif( x()==1, 0.02083269071095121, 0);
val+=iif( x()==2, 0.020591074008640423, 0);
val+=iif( x()==3, 0.020587894424854085, 0);
val+=iif( x()==4, 0.02125898032182231, 0);
val

Mark
Takahashi Epsilon 180ED
H-alpha modified Sony A7S
http://www.markshelley.co.uk/Astronomy/

Offline gvanhau

  • PixInsight Old Hand
  • ****
  • Posts: 345
Re: Pixel Math If (Case or Switch statement)
« Reply #6 on: 2019 February 21 06:01:00 »
Hello

I dont have access to my PI computer right now, but I think something like this could work:

P(0)= 0.020749760758206493;
P(1)= 0.02083269071095121;
P(2)= 0.020591074008640423;
P(3)= 0.020587894424854085;
P(4)= 0.02125898032182231;
iif(x()>=0 && x()<5, P(x()),$T)

Asuming that we can declare P as an array

Regards
Geert
Geert Vanhauwaert