Skip to content

Commit 90d812c

Browse files
committed
1 parent 6ee9f99 commit 90d812c

File tree

8 files changed

+143
-4
lines changed

8 files changed

+143
-4
lines changed

GameMakerScripts.yyp

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# GameMaker Scripts
22

3-
A collection of general utility scripts for GameMaker Studio 2 (Version 2.3).
3+
A collection of general utility and mathematical functions for GameMaker Studio 2 (Version 2.3).
44

55
All scripts are included in the `scripts/` folder of this repository. Each script defines a single function. Most functions are standalone and are meant to be taken à la carte, but some of the more mathematically complicated functions depend on other scripts, indicated in a `@requires` tag. All function names begin with an underscore (`_`) in order to distinguish them from built-in functions.
66

@@ -19,6 +19,13 @@ Common array functions (such as searching and counting).
1919
* [`_permute`](https://github.com/adam-rumpf/game-maker-scripts/blob/master/scripts/_permute/_permute.gml): Permutes the elements of an array according to a given permutation array.
2020
* [`_range`](https://github.com/adam-rumpf/game-maker-scripts/blob/master/scripts/_range/_range.gml): Generates an array of equally-spaced values over a specified range with a specified step size.
2121

22+
## Computational Mathematics Functions
23+
24+
Numerical algorithms for computational mathematics.
25+
26+
* [`_root_bisection`](https://github.com/adam-rumpf/game-maker-scripts/blob/master/scripts/_root_bisection/_root_bisection.gml): Finds a function root on a specified interval using the bisection method.
27+
* [`_root_newton`](https://github.com/adam-rumpf/game-maker-scripts/blob/master/scripts/_root_newton/_root_newton.gml): Finds a function root given a derivative and an initial guess using Newton's method.
28+
2229
## Linear Algebra Functions
2330

2431
Common linear algebra algorithms for dealing with matrices and vectors. In all functions, _vectors_ are considered to be 1D arrays while _matrices_ are 2D arrays.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/// @func _array_function(f, arr)
2+
/// @desc Applies a given function to every value in an array.
3+
/// @func {function} f Function to be applied. Should accept a single input.
4+
/// @func {*[]} arr 1D array to apply function to.
5+
/// @return {*[]} Array consisting of f applied to every value in arr.
6+
7+
function _array_function(f, arr)
8+
{
9+
// Get array size
10+
var n = array_length(arr);
11+
12+
// Apply function to all values in input array
13+
var out = array_create(n); // output array
14+
for (var i = 0; i < n; i++)
15+
out[i] = f(arr[i]);
16+
17+
// Return output array
18+
return out;
19+
}

scripts/_array_max/_array_max.gml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/// @func _array_max(arr[, val=true])
1+
/// @func _array_max(arr[, val])
22
/// @desc Finds the maximum value (or its index) in an array.
33
/// @param {real[]} arr Array to search.
44
/// @param {bool} [val=true] If true the maximum value is returned, if false the (first) index of the maximum value is returned.

scripts/_array_min/_array_min.gml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/// @func _array_min(arr[, val=true])
1+
/// @func _array_min(arr[, val])
22
/// @desc Finds the minimum value (or its index) in an array.
33
/// @param {real[]} arr Array to search.
44
/// @param {bool} [val=true] If true the minimum value is returned, if false the (first) index of the minimum value is returned.

scripts/_random_weighted_index/_random_weighted_index.gml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/// @func _random_weighted_index(wt)
22
/// @desc Returns a random array index with probabilities defined by a given weight array.
3-
/// @param {*[]} wt Array of weights (corresponding to indices 0, 1, 2, ...).
3+
/// @param {real[]} wt Array of weights (corresponding to indices 0, 1, 2, ...). Negative weights are treated as zero.
44
/// @return {int} Randomly chosen array index.
55

66
function _random_weighted_index(wt)
@@ -10,7 +10,13 @@ function _random_weighted_index(wt)
1010
tot = 0.0; // total weight
1111
n = array_length(wt); // number of indices
1212
for (var i = 0; i < n; i++)
13+
{
14+
// Ignore negative weights
15+
if (wt[i] < 0)
16+
continue;
17+
1318
tot += wt[i];
19+
}
1420

1521
// Generate a random number
1622
var r = random_range(0, tot);
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/// @func _root_bisection(f, a, b[, err[, cutoff]])
2+
/// @func Finds the root of a real-valued function on a specified interval using the bisection method.
3+
/// @param {function} f Function (which maps reals to reals) to find the root of. The signs of f(a) and f(b) must be opposite.
4+
/// @param {real} a Lower bound of search interval.
5+
/// @param {real} b Upper bound of search interval.
6+
/// @param {real} [err=0.01] Error bound to define stopping criterion. The search ends as soon as the bound falls below this value.
7+
/// @param {int} [cutoff=100] Iteration cutoff. The search ends as soon as the number of iterations crosses this bound, regardless of the error.
8+
/// @return {real} Estimate of root (or undefined in case of problem).
9+
10+
function _root_bisection(f, a, b)
11+
{
12+
// Check for optional arguments
13+
var err = (argument_count > 3 ? argument[3] : 0.01);
14+
var cutoff = (argument_count > 4 ? argument[4] : 100);
15+
16+
// Test for trivial roots at boundaries
17+
if (f(a) == 0)
18+
return a;
19+
if (f(b) == 0)
20+
return b;
21+
22+
// Verify that sign of function is opposite on boundaries
23+
if (sign(f(a)) == sign(f(b)))
24+
return undefined;
25+
26+
// Define local variables for boundaries
27+
var lb, ub;
28+
lb = a; // lower bound
29+
ub = b; // upper bound
30+
31+
// Ensure that boundaries are in order
32+
if (lb >= ub)
33+
{
34+
lb = b;
35+
ub = a;
36+
}
37+
38+
// Main search loop (error bound equals half of search interval)
39+
var iter = 0; // iteration number
40+
while (((ub - lb)/2 > err) && (iter < cutoff))
41+
{
42+
iter++;
43+
44+
// Find midpoint and its sign
45+
var mid, midsign;
46+
mid = mean(lb, ub);
47+
midsign = sign(f(mid));
48+
49+
// Check whether midpoint is a root
50+
if (f(mid) == 0)
51+
return mid;
52+
53+
// Choose upper or lower subinterval so that signs of endpoints remain opposite
54+
if (midsign == sign(f(lb)))
55+
lb = mid;
56+
else
57+
ub = mid;
58+
}
59+
60+
// Return final midpoint
61+
return mean(lb, ub);
62+
}

scripts/_root_newton/_root_newton.gml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/// @func _root_newton(f, fp, x0[, err[, cutoff]])
2+
/// @func Finds the root of a real-valued, differentiable function for an initial guess using Newton's method.
3+
/// @param {function} f Differentiable function (which maps reals to reals) to find the root of.
4+
/// @param {function} fp First derivative of function.
5+
/// @param {real} x0 Initial guess.
6+
/// @param {real} [err=0.01] Error bound to use as a cutoff criterion. The search ends as soon as the absolute function value falls below this bound.
7+
/// @param {int} [cutoff=100] Iteration cutoff. The search ends as soon as the number of iterations crosses this bound, regardless of the error.
8+
/// @return {real} Estimate of root (or undefined in case of problem).
9+
10+
function _root_newton(f, fp, x0)
11+
{
12+
// Check for optional arguments
13+
var err = (argument_count > 3 ? argument[3] : 0.01);
14+
var cutoff = (argument_count > 4 ? argument[4] : 100);
15+
16+
// Initialize guess and corresponding function values
17+
var xx, fx, fpx;
18+
xx = x0; // current guess
19+
fx = f(xx); // function value for current guess
20+
fpx = fp(xx); // derivative of function guess
21+
22+
// Main search loop (error is absolute value of function value)
23+
var iter = 0; // iteration number
24+
while ((abs(fx) > err) && (iter < cutoff))
25+
{
26+
iter++;
27+
28+
// Check for division by zero
29+
if (fpx == 0)
30+
return undefined;
31+
32+
// Newton iteration
33+
xx -= fx/fpx;
34+
35+
// Update function values
36+
fx = f(xx);
37+
fpx = fp(xx);
38+
}
39+
40+
// Return latest guess
41+
return xx;
42+
}

0 commit comments

Comments
 (0)