You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
As a note, the Hutchinson redesign (#64) currently allows for users to specify hutchinson operators (and technically shaders) like so:
H = Hutchinson(f_1, (f_2, f_3, f_4, f_5), f_6)
Which means: execute f_1, then choose between f_2 -> f_5, then execute f_6, but we could imagine:
H = Hutchinson(f_1, ((f_2, f_3), f_4, f_5), f_6)
Which would mean: execute f_1, then choose between (f_2, f_3), f_4, or f_5, then execute f_6. This Cannot be done right now because I don't have a way to reason about a choice between f_2 and f_3 as one of the choices in another IFS. A simple strategy would be to set FractalOperators as a super type and create a null struct:
struct NullOperator <: FractalOperator
prob::Number
fos::Tuple{FractalOperator}
end
Then we would store [f_1, f_null, f_4, f_5, f_2, f_3, f_null, f_6] with fnums of [1,3,2,1] and potentially another set of indices like fstarts = [1, 2, 5, 7] so if we have 2 or more recursive IFS definitions, we can keep track of where we are on the list. We could probably get rid of the list of lists entirely in this case and just do everything in the kernel instead...
We also need to think about how users will write down both the probability of the null operator and the other functions in a reasonable way, maybe...
I think I'm overthinking this. It should be possible for the user to implement everything they want for the "game" part of the chaos game. So, Fable handles the iteration, but the user can write custom compute kernels by abusing the fum syntax?
Otherwise, the core problem here is that we use the fid construct to iterate over functions. This means that we generate a single random number that is used for all functions. This is nice in a way for performance, but if the user is implementing tuples of tuples where we know the probabilities, we can probably just use those instead and make a function choice on-the-fly.
I am not sure how this would play with the @generated functions used to iterate over different fx tuples, ie:
# These functions essentially unroll the loops in the kernel because of a
# known julia bug preventing us from using for i = 1:10...
@generated function pt_loop(fxs, fid, pt, frame, fnums, kwargs)
exs = Expr[]
push!(exs, :(bit_offset = 0))
push!(exs, :(fx_offset = 0))
for i = 1:length(fnums.parameters)
ex = quote
idx = decode_fid(fid, bit_offset, fnums[$i]) + fx_offset
pt = call_pt_fx(fxs, pt, frame, kwargs, idx)
bit_offset += ceil(UInt,log2(fnums[$i]))
fx_offset += fnums[$i]
end
push!(exs, ex)
end
push!(exs, :(return pt))
# to return 3 separate colors to mix separately
# return :(Expr(:tuple, $exs...))
return Expr(:block, exs...)
end
We could either change this to do some form of DFS over the fx tuple provided (maybe some sort of stack-like implementation while unrolling the while loop?), or we allow the fids to accept conditional probabilities and such.
As a note, the Hutchinson redesign (#64) currently allows for users to specify hutchinson operators (and technically shaders) like so:
Which means: execute
f_1
, then choose betweenf_2 -> f_5
, then executef_6
, but we could imagine:Which would mean: execute
f_1
, then choose between(f_2, f_3)
,f_4
, orf_5
, then executef_6
. This Cannot be done right now because I don't have a way to reason about a choice betweenf_2
andf_3
as one of the choices in another IFS. A simple strategy would be to set FractalOperators as a super type and create a null struct:Then we would store
[f_1, f_null, f_4, f_5, f_2, f_3, f_null, f_6]
with fnums of[1,3,2,1]
and potentially another set of indices likefstarts = [1, 2, 5, 7]
so if we have 2 or more recursive IFS definitions, we can keep track of where we are on the list. We could probably get rid of the list of lists entirely in this case and just do everything in the kernel instead...We also need to think about how users will write down both the probability of the null operator and the other functions in a reasonable way, maybe...
With
fo(fos::Tuple{FractalOperator}; prob = 0) = NullOperator(prob, fos)
Or something.
The text was updated successfully, but these errors were encountered: