Skip to content

Commit 52ec7fc

Browse files
committed
showcase
1 parent d0f0bb0 commit 52ec7fc

File tree

2 files changed

+76
-2
lines changed

2 files changed

+76
-2
lines changed

docs/Showcase.ipynb

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,79 @@
340340
"w_func(ratings)"
341341
]
342342
},
343+
{
344+
"cell_type": "markdown",
345+
"metadata": {},
346+
"source": [
347+
"Here is a simple but fully working example with all moving parts, demonstrating the use in the context of an HVAC system.\n",
348+
"\n",
349+
"It also demonstrates the three different ways to set up complex combinations of rules: you can either define each rule one by one and then combine them via the | operator, or you can put the rules into a list and use sum(..) to combine them into one in a single step, or you can define one big and complex rule right from the start. Which way best suits your needs depends on how complex each rule is and how/where you define them in your code and whether you need to use them in different places in different combinations."
350+
]
351+
},
352+
{
353+
"cell_type": "code",
354+
"execution_count": 11,
355+
"metadata": {
356+
"execution": {
357+
"iopub.execute_input": "2021-04-07T21:45:52.904997Z",
358+
"iopub.status.busy": "2021-04-07T21:45:52.904298Z",
359+
"iopub.status.idle": "2021-04-07T21:45:53.028508Z",
360+
"shell.execute_reply": "2021-04-07T21:45:53.027448Z",
361+
"shell.execute_reply.started": "2021-04-07T21:45:52.904955Z"
362+
}
363+
},
364+
"outputs": [
365+
{
366+
"name": "stdout",
367+
"output_type": "stream",
368+
"text": [
369+
"1611.3704197201866 None 1656.5076659966692 None => 1633.939042858428\n"
370+
]
371+
}
372+
],
373+
"source": [
374+
"from fuzzylogic.classes import Domain, Set, Rule\n",
375+
"from fuzzylogic.hedges import very\n",
376+
"from fuzzylogic.functions import R, S\n",
377+
"\n",
378+
"temp = Domain(\"Temperature\", -80, 80)\n",
379+
"hum = Domain(\"Humidity\", 0, 100)\n",
380+
"motor = Domain(\"Speed\", 0, 2000)\n",
381+
"\n",
382+
"temp.cold = S(0,20)\n",
383+
"temp.hot = R(15,30)\n",
384+
"\n",
385+
"hum.dry = S(20,50)\n",
386+
"hum.wet = R(40,70)\n",
387+
"\n",
388+
"motor.fast = R(1000,1500)\n",
389+
"motor.slow = ~motor.fast\n",
390+
"\n",
391+
"R1 = Rule({(temp.hot, hum.dry): motor.fast})\n",
392+
"R2 = Rule({(temp.cold, hum.dry): very(motor.slow)})\n",
393+
"R3 = Rule({(temp.hot, hum.wet): very(motor.fast)})\n",
394+
"R4 = Rule({(temp.cold, hum.wet): motor.slow})\n",
395+
"\n",
396+
"rules = Rule({(temp.hot, hum.dry): motor.fast,\n",
397+
" (temp.cold, hum.dry): very(motor.slow),\n",
398+
" (temp.hot, hum.wet): very(motor.fast),\n",
399+
" (temp.cold, hum.wet): motor.slow,\n",
400+
" })\n",
401+
"\n",
402+
"rules == R1 | R2 | R3 | R4 == sum([R1, R2, R3, R4])\n",
403+
"\n",
404+
"values = {hum: 45, temp: 22}\n",
405+
"print(R1(values), R2(values), R3(values), R4(values), \"=>\", rules(values))"
406+
]
407+
},
408+
{
409+
"cell_type": "markdown",
410+
"metadata": {},
411+
"source": [
412+
"There are a few things to note in this example. Firstly, make sure to pass in the values as a single dictionary at the end, not as parameters.\n",
413+
"If a rule has zero weight - in this example a temp of 22 results in cold weighted with S(0,20) as 0 - the Rule returns None, which makes sure this condition is ignored in subsequent calculations. Also you might notice that the result is a value of 1633, which is way more than motor.fast with R(1000,1500) would suggest. However, since the domain motor is defined between 0 and 2000, the center of gravity method used for evaluation takes many of the values between 1500 and 2000 weighted with 1 into account, giving this slightly unexpected result."
414+
]
415+
},
343416
{
344417
"cell_type": "markdown",
345418
"metadata": {},

src/fuzzylogic/classes.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -409,11 +409,12 @@ def __eq__(self, other):
409409
def __getitem__(self, key):
410410
return self.conditions[frozenset(key)]
411411

412-
def __call__(self, args:"dict[Domain]", method="cog"):
412+
def __call__(self, args:"dict[Domain, float]", method="cog"):
413413
"""Calculate the infered value based on different methods.
414414
Default is center of gravity.
415415
"""
416-
assert len(args) == max(len(c) for c in self.conditions.keys()), "Number of arguments must correspond to the number of domains!"
416+
assert len(args) == max(len(c) for c in self.conditions.keys()), "Number of values must correspond to the number of domains defined as conditions!"
417+
assert isinstance(args, dict), "Please make sure to pass in the values as a dictionary."
417418
if method == "cog":
418419
actual_values = {f: f(args[f.domain]) for S in self.conditions.keys() for f in S}
419420
weights = [(v, x) for K, v in self.conditions.items()

0 commit comments

Comments
 (0)