- Calculating a sequence of functions using iterationCalculating a sequence of functions using iteration
- Multiple generators for iterative construction of fractalsMultiple generators for iterative construction of fractals
I notice some striking similarities between this question and the following two:
- Calculating a sequence of functions using iteration
- Multiple generators for iterative construction of fractals
Presumably, the user is the same, which conceals information about your mathematical and programming background - information that's useful to potential answers. Nonetheless, the question is interesting, so here's a go.
As I understand it, you're simultaneously generating two functions $y(x)$ and $z(x)$ on $[0,1]$. The $n^{\text{th}}$ approximations $y_n(x)$ and $z_n(x)$ are piecewise linear functions starting with $y_0(x)=z_0(x)=x$. You have two partitions of $[0,1]$, namely $$0<a_1<a_2<\cdots<a_8<1$$ and $$0<c_1<c_2<\cdots<c_8<1.$$ Each of $y_n(x)$ and $z_n(x)$ will be constructed by first randomly choosing one of those partitions (one for $y$ and one for $z$) and then placing scaled copies of either $y_{n-1}$ or $z_{n-1}$ (also chosen randomly and independently for each sub-interval) over each of the nine sub-intervals in the partition.
The main problem with your code, is that you're repeating tremendous amounts of code, rather than encapsulating repetitive stuff into functions. For example, you define y0, y1, y2, y3, and y4 using the exact same code with suitable replacements. Why not define a function and then recursively define y[n]?
Here's one approach:
(* Your as and cs *) (* One partition will be randomly chosen for each step *) partitions = { Partition[{0.0, 0.25, 0.28, 0.3, 0.32, 0.7, 0.73, 0.78, 0.8, 1.0}, 2, 1], Partition[{0.0, 0.2, 0.25, 0.28, 0.32, 0.6, 0.7, 0.8, 0.83, 1.0}, 2, 1] }; (* Your bs and ds *) compressions = { Partition[{0, 0.4, 0.22, 0.26, 0.1, 0.8, 0.6, 0.8, 0.6, 1}, 2, 1], Partition[{0, 0.45, 0.3, 0.45, 0.2, 0.75, 0.65, 0.7, 0.6, 1}, 2, 1] }; transform[f_, x_, {a1_, a2_}, {b1_, b2_}] := (b2 - b1)*(f /. x -> (x - a1)/(a2 - a1)) + b1; next[{y_, z_}, x_] := With[{ part = RandomChoice[partitions], bs = RandomChoice[compressions]}, Piecewise[Table[ {transform[RandomChoice[{y, z}], x, part[[k]], bs[[k]]], part[[k, 1]] <= x <= part[[k, 2]]}, {k, 1, Length[partitions[[1]]]}]]]; Note that next accepts two expressions of x, rather than functions. It then returns a single Piecewise defined expression. The recursion can be implemented as follows:
Clear[y, z]; y[0] = z[0] = x; y[n_] := y[n] = next[{y[n - 1], z[n - 1]}, x]; z[n_] := z[n] = next[{y[n - 1], z[n - 1]}, x]; We now graph it.
GraphicsGrid[Table[Plot[#, {x, 0, 1}] & /@ {y[n], z[n]}, {n, 1, 4}]] An alternative approach is to use functional iteration.
step[{y_, z_}, x_] := {next[{y, z}, x], next[{y, z}, x]}; iterated = NestList[step[#, x] &, {x, x}, 4]; GraphicsGrid[Map[Plot[#, {x, 0, 1}] &, Rest[iterated], {2}]] In either case, the graphs look like so:
