Attempting to follow Karl Sims work and decided to use GMIC as a means of visualizing, so I made a script that compiles a random GMIC fill string.
A lot of the time, the output is just a single value, or really boring, but it is random, so you could technically stumble across an equation that recreates the Mona Lisa as a sum of oscillating wave functions. This is just the start, I’ll update this post with my progress towards achieving Sims implementation of symbolic expression evolution. In the next update, I will have hopefully implemented mutation and multichannel expressions.
HELP: I am having trouble with the modulo operator % dividing by zero. Due to the random nature of the output, I can’t control if it will be a zero or not. I know that 1/0 returns nan, is there anyway to suppress a n%0 in a similar way?
I’m confused as to what this is doing. Do I put this before the expression? How would this work in the math expression–there is not mod() function for the math evaluator?
The possible ways of getting a n%0 could be from a variable or a constant or another expression that could evaluate to zero (n%sin(pi*x)). I don’t think it’s feasible to check and make sure every instance of a % will never be n%0. Is there a way to inject a onfail statement into the math evaluator?
You have to use onfail on a local statement, but regarding this, I’ll leave it to David due to his more experience in use of onfail. There are zero result on “onfail” in my gmic-community code.
gosgood@lydia ~ $ gmic a='{1/0}' echo \$a
[gmic]-0./ Start G'MIC interpreter.
[gmic]-0./ Set local variable 'a=inf'.
inf
[gmic]-0./ End G'MIC interpreter.
I think isexpr() is your friend. Returns True if its math expression argument is valid, otherwise it returns False. 1%0 is not a valid math expression.
gosgood@lydia ~ $ gmic a='{isexpr(b=26%3)?b:nan}'
[gmic]-0./ Start G'MIC interpreter.
[gmic]-0./ Set local variable 'a=2'.
[gmic]-0./ End G'MIC interpreter.
gosgood@lydia ~ $ gmic a='{isexpr(b=26%0)?b:nan}'
[gmic]-0./ Start G'MIC interpreter.
[gmic]-0./ Set local variable 'a=nan'.
[gmic]-0./ End G'MIC interpreter.
So the game is to wrap a math expression that can be invalid from time to time with isexpr() return its result when it is valid, and return a flag value when it is not.
No, it isn’t. Only works if the right hand value of % is a known constant at JIT compile time. If the right hand value is dynamic, a math expression exception is thrown at runtime whenever the righthand side resolves to zero. For me, that leaves the pipeline interpreter’s local[]<test math expression>onfail echo 'Oooops!' done construct, as @Reptorian observed.
gosgood@lydia ~ $ gmic local a={1%0} onfail echo 'Oooops! '\$a done
[gmic]-0./ Start G'MIC interpreter.
[gmic]-0./*local/ *** Error *** Item substitution '{1%0}': Specified modulo value is 0.
Oooops! $a
You get the exception thrown message, but pipeline processing continues in the onfail section.
Thank you. I suppose I could create the image and then wrap a fill command in the onfail block; however, I hesitate to allow the failure of one component determine the expression at the point. Consider the following:
Assuming that the left side of the * evaluates to 1, the right hand side of the equation is preserved. If the left hand side evaluates to an error and the error is caught and the pixel is given a uniform value, the right hand side is entirely unexpressed.
Of course, right now, the (isnan(1%0)==1) doesn’t work which I find rather strange. Given the many, many, allowanced GMIC’s math evaluator makes for things like inf/inf and 0/0, why cant n%0 return something like nan or inf to allow for continued arithmetic? I don’t know if there are technical details on why n%0 can’t return something, but from an consistency standpoint, I don’t see a reason to have only one math operator that throws an error. I’m not sure if other operators can throw errors like this, but % seems common enough to have an allowance, or special case like normalize’s _constant_case_ratio.
I apologize for the rant. I do see @Reptorian 's method as a valid workaround; having a custom mod function isn’t too much of a hassle; but, for reasons mentioned above, why can’t it be default?
I would like to make a modification to demonstrate what I believe should be the proper response to n%0: In the case of n%0 return nan
@Reptorian is right, a work-around is to preprend the string "mod(a,b) = (b?a%b:nan);" to your expression before the evaluation.
You are actually right about having this behavior as default when using the % operator (modulo). I’ve thrown an error instead of returning nan, simply because this is what is done in C/C++ when you try to do a modulo with zero.
But in the context of G’MIC, I believe returning nan would be better. I’ll make the necessary changes for next version 3.2.6.