shithub: slug

Download patch

ref: 70de7329ed0cdf8dac3e7e9126f13e5ed61d2c28
parent: 9853749352c8acaf7ddb4e0c4fef457008a95bba
author: phil9 <telephil9@gmail.com>
date: Mon Dec 5 00:42:59 EST 2022

implement randomGaussian()

--- a/a.h
+++ b/a.h
@@ -30,6 +30,8 @@
 int		registerpixels(lua_State*);
 void	lpushpixels(lua_State*);
 
+double	randomgaussian(double, double);
+
 extern int		drawing;
 extern int		looping;
 extern int		framerate;
--- a/api.c
+++ b/api.c
@@ -592,6 +592,31 @@
 	return 0;
 }
 
+int
+crandomgaussian(lua_State *L)
+{
+	double m, s, g;
+	int n;
+
+	m = 0.0;
+	s = 1.0;
+	n = lua_gettop(L);
+	switch(n){
+	case 2:
+		s = luaL_checknumber(L, 2);
+	case 1:
+		m = luaL_checknumber(L, 1);
+		break;
+	case 0:
+		break;
+	default:
+		luaL_error(L, "invalid argument count");
+	}
+	g = randomgaussian(m, s);
+	lua_pushnumber(L, g);
+	return 1;
+}
+
 void
 registerfunc(lua_State *L, const char *name, int(*f)(lua_State*))
 {
@@ -641,5 +666,6 @@
 	registerfunc(L, "color", ccolor);
 	registerfunc(L, "loadPixels", cloadpixels);
 	registerfunc(L, "updatePixels", cupdatepixels);
+	registerfunc(L, "randomGaussian", crandomgaussian);
 }
 
--- /dev/null
+++ b/math.c
@@ -1,0 +1,26 @@
+#include "a.h"
+
+double
+randomgaussian(double mean, double sd)
+{
+	static int prev = 0;
+	static double y2;
+	double y1, x1, x2, w;
+
+	if(prev){
+		y1 = y2;
+		prev = 0;
+	}else{
+		do{
+			x1 = 2*frand() - 1;
+			x2 = 2*frand() - 1;
+			w = x1 * x1 + x2 * x2;
+		}while(w >= 1);
+		w = sqrt(-2 * log(w) / w);
+		y1 = x1 * w;
+		y2 = x2 * w;
+		prev = 1;
+	}
+	return y1 * sd + mean;
+}
+
--- a/mkfile
+++ b/mkfile
@@ -4,7 +4,7 @@
 TARG=slug
 LIB=lua/liblua.a.$O
 HFILES=a.h
-OFILES=slug.$O api.$O color.$O pixels.$O
+OFILES=slug.$O api.$O color.$O pixels.$O math.$O
 MAN=/sys/man/1
 
 </sys/src/cmd/mkone
--- /dev/null
+++ b/samples/gaussian.lua
@@ -1,0 +1,14 @@
+#!/bin/slug
+
+function setup()
+	size(400, 400)
+	background(200)
+	for y = 0, 399 do
+		x = math.floor(randomGaussian() * 60)
+		line(200, y, 200 + x, y)
+	end
+end
+
+function draw()
+end
+
--- a/slug.man
+++ b/slug.man
@@ -298,6 +298,16 @@
 .TP
 \f5mouseY
 Global variable containing the vertical coordinate of the mouse.
+.SS Math
+.TP
+\f5randomGaussian()
+.PD 0
+.TP
+\f5randomGaussian(\f2mean\fP)
+.PD 0
+.TP
+\f5randomGaussian(\f2mean\fP, \f2stddev\fP)
+Returns a random number fitting a Gaussian (or normal) distribution. The arguments are the mean and the standard deviation which defaults to 0.0 and 1.0 respectively.
 
 .SH AUTHOR
 phil9