liba 0.1.15

An algorithm library based on C/C++
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
/***
 membership function
 @module liba.mf
*/

#include "a.h"
#include "a/mf.h"

/***
 gaussian membership function
 @tparam number x input value for which to compute membership value.
 @tparam number sigma is the standard deviation.
 @tparam number c is the mean.
 @treturn number membership value.
 @function gauss
*/
static int liba_mf_gauss_(lua_State *L, int arg)
{
    a_float const x = (a_float)luaL_checknumber(L, arg + 1);
    a_float const sigma = (a_float)luaL_checknumber(L, arg + 2);
    a_float const c = (a_float)luaL_checknumber(L, arg + 3);
    lua_pushnumber(L, (lua_Number)a_mf_gauss(x, sigma, c));
    return 1;
}
static int liba_mf_gauss(lua_State *L)
{
    return liba_mf_gauss_(L, 0);
}

/***
 product of two sigmoidal membership functions
 @tparam number x input value for which to compute membership value.
 @tparam number sigma1 is the standard deviation of the left gaussian function.
 @tparam number c1 is the mean of the left gaussian function.
 @tparam number sigma2 is the standard deviation of the right gaussian function.
 @tparam number c2 is the mean of the right gaussian function.
 @treturn number membership value.
 @function gauss2
*/
static int liba_mf_gauss2_(lua_State *L, int arg)
{
    a_float const x = (a_float)luaL_checknumber(L, arg + 1);
    a_float const sigma1 = (a_float)luaL_checknumber(L, arg + 2);
    a_float const c1 = (a_float)luaL_checknumber(L, arg + 3);
    a_float const sigma2 = (a_float)luaL_checknumber(L, arg + 4);
    a_float const c2 = (a_float)luaL_checknumber(L, arg + 4);
    lua_pushnumber(L, (lua_Number)a_mf_gauss2(x, sigma1, c1, sigma2, c2));
    return 1;
}
static int liba_mf_gauss2(lua_State *L)
{
    return liba_mf_gauss2_(L, 0);
}

/***
 generalized bell-shaped membership function
 @tparam number x input value for which to compute membership value.
 @tparam number a defines the width of the membership function, where a larger value creates a wider membership function.
 @tparam number b defines the shape of the curve on either side of the central plateau, where a larger value creates a more steep transition.
 @tparam number c defines the center of the membership function.
 @treturn number membership value.
 @function gbell
*/
static int liba_mf_gbell_(lua_State *L, int arg)
{
    a_float const x = (a_float)luaL_checknumber(L, arg + 1);
    a_float const a = (a_float)luaL_checknumber(L, arg + 2);
    a_float const b = (a_float)luaL_checknumber(L, arg + 3);
    a_float const c = (a_float)luaL_checknumber(L, arg + 4);
    lua_pushnumber(L, (lua_Number)a_mf_gbell(x, a, b, c));
    return 1;
}
static int liba_mf_gbell(lua_State *L)
{
    return liba_mf_gbell_(L, 0);
}

/***
 sigmoidal membership function
 @tparam number x input value for which to compute membership value.
 @tparam number a defines the width of the transition area.
 @tparam number c defines the center of the transition area.
 @treturn number membership value.
 @function sig
*/
static int liba_mf_sig_(lua_State *L, int arg)
{
    a_float const x = (a_float)luaL_checknumber(L, arg + 1);
    a_float const a = (a_float)luaL_checknumber(L, arg + 2);
    a_float const c = (a_float)luaL_checknumber(L, arg + 3);
    lua_pushnumber(L, (lua_Number)a_mf_sig(x, a, c));
    return 1;
}
static int liba_mf_sig(lua_State *L)
{
    return liba_mf_sig_(L, 0);
}

/***
 difference between two sigmoidal membership functions
 @tparam number x input value for which to compute membership value.
 @tparam number a1 defines the width of the first transition area.
 @tparam number c1 defines the center of the first transition area.
 @tparam number a2 defines the width of the second transition area.
 @tparam number c2 defines the center of the second transition area.
 @treturn number membership value.
 @function dsig
*/
static int liba_mf_dsig_(lua_State *L, int arg)
{
    a_float const x = (a_float)luaL_checknumber(L, arg + 1);
    a_float const a1 = (a_float)luaL_checknumber(L, arg + 2);
    a_float const c1 = (a_float)luaL_checknumber(L, arg + 3);
    a_float const a2 = (a_float)luaL_checknumber(L, arg + 4);
    a_float const c2 = (a_float)luaL_checknumber(L, arg + 4);
    lua_pushnumber(L, (lua_Number)a_mf_dsig(x, a1, c1, a2, c2));
    return 1;
}
static int liba_mf_dsig(lua_State *L)
{
    return liba_mf_dsig_(L, 0);
}

/***
 product of two sigmoidal membership functions
 @tparam number x input value for which to compute membership value.
 @tparam number a1 defines the width of the first transition area.
 @tparam number c1 defines the center of the first transition area.
 @tparam number a2 defines the width of the second transition area.
 @tparam number c2 defines the center of the second transition area.
 @treturn number membership value.
 @function psig
*/
static int liba_mf_psig_(lua_State *L, int arg)
{
    a_float const x = (a_float)luaL_checknumber(L, arg + 1);
    a_float const a1 = (a_float)luaL_checknumber(L, arg + 2);
    a_float const c1 = (a_float)luaL_checknumber(L, arg + 3);
    a_float const a2 = (a_float)luaL_checknumber(L, arg + 4);
    a_float const c2 = (a_float)luaL_checknumber(L, arg + 4);
    lua_pushnumber(L, (lua_Number)a_mf_psig(x, a1, c1, a2, c2));
    return 1;
}
static int liba_mf_psig(lua_State *L)
{
    return liba_mf_psig_(L, 0);
}

/***
 trapezoidal membership function
 @tparam number x input value for which to compute membership value.
 @tparam number a defines its left foot.
 @tparam number b defines its left shoulder.
 @tparam number c defines its right shoulder.
 @tparam number d defines its right foot.
 @treturn number membership value.
 @function trap
*/
static int liba_mf_trap_(lua_State *L, int arg)
{
    a_float const x = (a_float)luaL_checknumber(L, arg + 1);
    a_float const a = (a_float)luaL_checknumber(L, arg + 2);
    a_float const b = (a_float)luaL_checknumber(L, arg + 3);
    a_float const c = (a_float)luaL_checknumber(L, arg + 4);
    a_float const d = (a_float)luaL_checknumber(L, arg + 4);
    lua_pushnumber(L, (lua_Number)a_mf_trap(x, a, b, c, d));
    return 1;
}
static int liba_mf_trap(lua_State *L)
{
    return liba_mf_trap_(L, 0);
}

/***
 triangular membership function
 @tparam number x input value for which to compute membership value.
 @tparam number a defines its left foot.
 @tparam number b defines its peak.
 @tparam number c defines its right foot.
 @treturn number membership value.
 @function tri
*/
static int liba_mf_tri_(lua_State *L, int arg)
{
    a_float const x = (a_float)luaL_checknumber(L, arg + 1);
    a_float const a = (a_float)luaL_checknumber(L, arg + 2);
    a_float const b = (a_float)luaL_checknumber(L, arg + 3);
    a_float const c = (a_float)luaL_checknumber(L, arg + 4);
    lua_pushnumber(L, (lua_Number)a_mf_tri(x, a, b, c));
    return 1;
}
static int liba_mf_tri(lua_State *L)
{
    return liba_mf_tri_(L, 0);
}

/***
 linear s-shaped saturation membership function
 @tparam number x input value for which to compute membership value.
 @tparam number a defines its foot.
 @tparam number b defines its shoulder.
 @treturn number membership value.
 @function lins
*/
static int liba_mf_lins_(lua_State *L, int arg)
{
    a_float const x = (a_float)luaL_checknumber(L, arg + 1);
    a_float const a = (a_float)luaL_checknumber(L, arg + 2);
    a_float const b = (a_float)luaL_checknumber(L, arg + 3);
    lua_pushnumber(L, (lua_Number)a_mf_lins(x, a, b));
    return 1;
}
static int liba_mf_lins(lua_State *L)
{
    return liba_mf_lins_(L, 0);
}

/***
 linear z-shaped saturation membership function
 @tparam number x input value for which to compute membership value.
 @tparam number a defines its shoulder.
 @tparam number b defines its foot.
 @treturn number membership value.
 @function linz
*/
static int liba_mf_linz_(lua_State *L, int arg)
{
    a_float const x = (a_float)luaL_checknumber(L, arg + 1);
    a_float const a = (a_float)luaL_checknumber(L, arg + 2);
    a_float const b = (a_float)luaL_checknumber(L, arg + 3);
    lua_pushnumber(L, (lua_Number)a_mf_linz(x, a, b));
    return 1;
}
static int liba_mf_linz(lua_State *L)
{
    return liba_mf_linz_(L, 0);
}

/***
 s-shaped membership function
 @tparam number x input value for which to compute membership value.
 @tparam number a defines its foot.
 @tparam number b defines its shoulder.
 @treturn number membership value.
 @function s
*/
static int liba_mf_s_(lua_State *L, int arg)
{
    a_float const x = (a_float)luaL_checknumber(L, arg + 1);
    a_float const a = (a_float)luaL_checknumber(L, arg + 2);
    a_float const b = (a_float)luaL_checknumber(L, arg + 3);
    lua_pushnumber(L, (lua_Number)a_mf_s(x, a, b));
    return 1;
}
static int liba_mf_s(lua_State *L)
{
    return liba_mf_s_(L, 0);
}

/***
 z-shaped membership function
 @tparam number x input value for which to compute membership value.
 @tparam number a defines its shoulder.
 @tparam number b defines its foot.
 @treturn number membership value.
 @function z
*/
static int liba_mf_z_(lua_State *L, int arg)
{
    a_float const x = (a_float)luaL_checknumber(L, arg + 1);
    a_float const a = (a_float)luaL_checknumber(L, arg + 2);
    a_float const b = (a_float)luaL_checknumber(L, arg + 3);
    lua_pushnumber(L, (lua_Number)a_mf_z(x, a, b));
    return 1;
}
static int liba_mf_z(lua_State *L)
{
    return liba_mf_z_(L, 0);
}

/***
 z-shaped membership function
 @tparam number x input value for which to compute membership value.
 @tparam number a defines its left foot.
 @tparam number b defines its left shoulder.
 @tparam number c defines its right shoulder.
 @tparam number d defines its right foot.
 @treturn number membership value.
 @function pi
*/
static int liba_mf_pi_(lua_State *L, int arg)
{
    a_float const x = (a_float)luaL_checknumber(L, arg + 1);
    a_float const a = (a_float)luaL_checknumber(L, arg + 2);
    a_float const b = (a_float)luaL_checknumber(L, arg + 3);
    a_float const c = (a_float)luaL_checknumber(L, arg + 4);
    a_float const d = (a_float)luaL_checknumber(L, arg + 4);
    lua_pushnumber(L, (lua_Number)a_mf_pi(x, a, b, c, d));
    return 1;
}
static int liba_mf_pi(lua_State *L)
{
    return liba_mf_pi_(L, 0);
}

/***
 membership function
 @tparam int e type for membership function
 @tparam number x input value for which to compute membership value.
 @tparam number ... is an array that stores parameters.
 @treturn number membership value.
 @function mf
*/
static int liba_mf_mf(lua_State *L)
{
    lua_Integer const e = luaL_checkinteger(L, 1);
    switch (e)
    {
    case A_MF_PI:
        return liba_mf_pi_(L, 1);
    case A_MF_Z:
        return liba_mf_z_(L, 1);
    case A_MF_S:
        return liba_mf_s_(L, 1);
    case A_MF_LINZ:
        return liba_mf_linz_(L, 1);
    case A_MF_LINS:
        return liba_mf_lins_(L, 1);
    case A_MF_TRI:
        return liba_mf_tri_(L, 1);
    case A_MF_TRAP:
        return liba_mf_trap_(L, 1);
    case A_MF_PSIG:
        return liba_mf_psig_(L, 1);
    case A_MF_DSIG:
        return liba_mf_dsig_(L, 1);
    case A_MF_SIG:
        return liba_mf_sig_(L, 1);
    case A_MF_GBELL:
        return liba_mf_gbell_(L, 1);
    case A_MF_GAUSS2:
        return liba_mf_gauss2_(L, 1);
    case A_MF_GAUSS:
        return liba_mf_gauss_(L, 1);
    case A_MF_NUL:
    default:
        return 0;
    }
}

static int liba_mf_(lua_State *L)
{
    lua_pushcfunction(L, liba_mf_mf);
    lua_replace(L, 1);
    lua_call(L, lua_gettop(L) - 1, 1);
    return 1;
}

int luaopen_liba_mf(lua_State *L)
{
    /***
     enumeration for membership function
     @field NUL none
     @field GAUSS gaussian membership function
     @field GAUSS2 gaussian combination membership function
     @field GBELL generalized bell-shaped membership function
     @field SIG sigmoidal membership function
     @field DSIG difference between two sigmoidal membership functions
     @field PSIG product of two sigmoidal membership functions
     @field TRAP trapezoidal membership function
     @field TRI triangular membership function
     @field LINS linear s-shaped saturation membership function
     @field LINZ linear z-shaped saturation membership function
     @field S s-shaped membership function
     @field Z z-shaped membership function
     @field PI pi-shaped membership function
     @table mf
    */
    static lua_int const enums[] = {
        {"NUL", A_MF_NUL},
        {"GAUSS", A_MF_GAUSS},
        {"GAUSS2", A_MF_GAUSS2},
        {"GBELL", A_MF_GBELL},
        {"SIG", A_MF_SIG},
        {"DSIG", A_MF_DSIG},
        {"PSIG", A_MF_PSIG},
        {"TRAP", A_MF_TRAP},
        {"TRI", A_MF_TRI},
        {"LINS", A_MF_LINS},
        {"LINZ", A_MF_LINZ},
        {"S", A_MF_S},
        {"Z", A_MF_Z},
        {"PI", A_MF_PI},
    };
    static lua_fun const funcs[] = {
        {"gauss", liba_mf_gauss},
        {"gauss2", liba_mf_gauss2},
        {"gbell", liba_mf_gbell},
        {"sig", liba_mf_sig},
        {"dsig", liba_mf_dsig},
        {"psig", liba_mf_psig},
        {"trap", liba_mf_trap},
        {"tri", liba_mf_tri},
        {"lins", liba_mf_lins},
        {"linz", liba_mf_linz},
        {"s", liba_mf_s},
        {"z", liba_mf_z},
        {"pi", liba_mf_pi},
        {"mf", liba_mf_mf},
    };
    lua_createtable(L, 0, A_LEN(enums) + A_LEN(funcs));
    lua_int_reg(L, -1, enums, A_LEN(enums));
    lua_fun_reg(L, -1, funcs, A_LEN(funcs));
    lua_createtable(L, 0, 1);
    lua_fun_set(L, -1, "__call", liba_mf_);
    lua_setmetatable(L, -2);
    return 1;
}