Fill a cocktail shaker with ice; add vodka, triple sec, cranberry, and lime, and shake well; strain into a chilled cocktail glass and garnish with orange twist (Cosmopolitan Cocktail Recipe)
This is a tribute to Blaise Pascal and Joseph Fourier, two of the greatest mathematicians in history. As Pascal did in his famous triangle, I generate a set of random curves (sines or cosines with random amplitudes between 1 and 50) and I arrange them over the lateral edges of the triangle. Each inner curve in the triangle is the sum of the two directly curves above it. This is the result for a 6 rows triangle:
Two comments:
- Inner curves are noisy. The greater is the distance from the edge, the higher the entropy. When I was a child, I used to play a game called the broken telephone; I can see some kind of connection between this graphic and the game.
- I have read that using
eval+parse
in sympton of being a bad programmer. Does anyone have an idea to do this in some other way without filling the screen of code?
This is the code:
library(ggplot2) library(gridExtra) nrows=6 for (i in 1:nrows){ eval(parse(text=paste("f",i,1,"=function(x) ", sample(c("sin(","cos("),1), runif(min=1, max=50,1) ,"*x)",sep=""))) eval(parse(text=paste("f",i,i,"=function(x) ", sample(c("sin(","cos("),1), runif(min=1, max=50,1) ,"*x)",sep="")))} for (i in 3:nrows) { for (j in 2:(i-1)) eval(parse(text=paste("f",i, j, "=function(x) f",(i-1),(j-1), "(x) + f",(i-1),j,"(x)",sep="")))} vplayout=function(x, y) viewport(layout.pos.row = x, layout.pos.col = y) opts=theme(legend.position="none", panel.background = element_rect(fill="gray95"), plot.background = element_rect(fill="gray95", colour="gray95"), panel.grid = element_blank(), axis.ticks=element_blank(), axis.title=element_blank(), axis.text =element_blank()) setwd("YOUR WORKING DIRECTORY HERE") grid.newpage() jpeg(file="Adding Waves.jpeg", width=1800,height=1000, bg = "gray95", quality = 100) pushViewport(viewport(layout = grid.layout(nrows, 2*nrows-1))) for (i in 1:nrows) { for (j in 1:i) { print(ggplot(data.frame(x = c(0, 20)), aes(x)) + stat_function(fun = eval(parse(text=paste("f",i,j,sep=""))), colour = "black", alpha=.75)+opts, vp = vplayout(i, nrows+(2*j-(i+1)))) } } dev.off()
So:
f<-function()
{
a<-sample(c(sin,cos),1)[[1]]
b<-sample(1:50,1)
function(x)
a(b*x)
}
replicate(11,f())
Pascal<-lapply(
2:6,
function(i)
c(f(),rep(NA,i-2),f())
)
Pascal<-c(f(),Pascal)
for(i in 3:6)
{
for(j in 2:(i-1))
{
k<-function()
{
f1<-Pascal[[i-1]][[j-1]]
f2<-Pascal[[i-1]][[j]]
function(x)
f1(x)+f2(x)
}
Pascal[[i]][[j]]<-k()
}
}
Pascal
Now you have a list of lists (rows and columns) of functions that you can evaluate with two nested lapply 🙂
Thank you! I get another idea from this another answer: http://www.datanalytics.com/2015/02/11/recurrencia-recurrente/