diff --git a/src/lib/par/nom-set.hpp b/src/lib/par/nom-set.hpp new file mode 100644 index 000000000..aaf00891c --- /dev/null +++ b/src/lib/par/nom-set.hpp @@ -0,0 +1,53 @@ +/* + NOM-SET.hpp - nominal scale domain + + Copyright (C) + 2026 Hermann Vosseler + +  **Lumiera** is free software; you can redistribute it and/or modify it +  under the terms of the GNU General Public License as published by the +  Free Software Foundation; either version 2 of the License, or (at your +  option) any later version. See the file COPYING for further details. + +*/ + + +/** @file nom-set.hpp + ** Collection of identifiers to constitute the domain for a nominal or ordinal scale. + ** The scale descriptor is used as delegate from the ParamType descriptor and maintained + ** within a global registry for sake of deduplication. It is expected that a lot of parameters + ** will share some common scales, like e.g. percentage values or decibels. The setup of a scale + ** may limit the value range, provide hints for the UI representation -- yet may possibly also + ** encompass nominal scales that comprise a selection of ID values. + ** + ** @todo WIP-WIP-WIP can be considered an initial draft and placeholder, as of 2026 + */ + + +#ifndef LIB_PAR_NOM_SET_H +#define LIB_PAR_NOM_SET_H + + +#include "lib/par/spec.hpp" + + +namespace lib { +namespace par { + + + + /** + * Interface: describe the properties of a value scale to use for parameters, + * including range limits and metric (linear, logarithmic). The core operation + * is to conform a value to this specific scale. + * @todo not clear if we want a virtual interface here....? + */ + class NomSet + { + public: + }; + + + +}} // namespace lib::par +#endif /*LIB_PAR_NOM_SET_H*/ diff --git a/src/lib/par/scale.hpp b/src/lib/par/scale.hpp index 85592e7f5..bad098f2f 100644 --- a/src/lib/par/scale.hpp +++ b/src/lib/par/scale.hpp @@ -1,5 +1,5 @@ /* - PARAM-TYPE.hpp - value scale to use for parameters + SCALE.hpp - value scale to use for parameters Copyright (C) 2026 Hermann Vosseler diff --git a/tests/16parameter.tests b/tests/16parameter.tests index 0d82402f0..9e1a93c40 100644 --- a/tests/16parameter.tests +++ b/tests/16parameter.tests @@ -20,3 +20,8 @@ END PLANNED "Parameter value scales" ParameterScale_test << END return: 0 END + + +PLANNED "Enumeration domains" NomSet_test << END +return: 0 +END diff --git a/tests/lib/par/nom-set-test.cpp b/tests/lib/par/nom-set-test.cpp new file mode 100644 index 000000000..bdcb4b5e5 --- /dev/null +++ b/tests/lib/par/nom-set-test.cpp @@ -0,0 +1,87 @@ +/* + NomSet(Test) - verify nominal and ordinal scale enumerations + + Copyright (C) + 2026, Hermann Vosseler + +  **Lumiera** is free software; you can redistribute it and/or modify it +  under the terms of the GNU General Public License as published by the +  Free Software Foundation; either version 2 of the License, or (at your +  option) any later version. See the file COPYING for further details. + +* *****************************************************************/ + +/** @file nom-set-test.cpp + ** unit test \ref NomSet_test + */ + + +#include "test/run.hpp" +//#include "test/test-helper.hpp" +#include "lib/par/nom-set.hpp" +#include "test/diagnostic-output.hpp"/////////////TODO + +//#include +//#include +//#include + +//using std::string; +//using std::vector; +//using std::swap; + + +namespace lib { +namespace par { +namespace test{ + +// using lumiera::error::LUMIERA_ERROR_LOGIC; + + namespace {//Test fixture.... + + }//(End)Test fixture + + + + + + + + + + /********************************************************************************//** + * @test document the definition of domain enumerations for nominal / ordinal scales. + */ + class NomSet_test : public Test + { + + virtual void + run (Arg) + { + simpleUsage(); + verify_typeMarker(); + } + + + void + simpleUsage() + { + UNIMPLEMENTED ("nebbich"); + } + + + /** @test + * @todo WIP 9/26 🔁 define ⟶ implement + */ + void + verify_typeMarker() + { + } + }; + + + /** Register this test class... */ + LAUNCHER (NomSet_test, "unit lib"); + + + +}}} // namespace lib::par::test diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 6e114af41..9af6f9350 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -82322,7 +82322,144 @@ - + + + + + + + +

+ Expanded list of levels of measurement +

+

+ Source: Nicholas C. Chrisman: Rethinking Levels of Measurement for Cartography (1998)
file:///Lager/Halde/Infoschrott/Texte/notiert/Rethinking levels of measurement for cartography | Nicholas R.Chrisman - Cartography and GIS, vol-25 p-231.1998.pdf +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Level of measurement + + Information required +
+ Nominal + + definitions of categories +
+ Graded membership + +
    +
  • + definition of categories +
  • +
  • + plus degree of membership +
  • +
  • + or distance from prototype +
  • +
+
+ Ordinal + + definitions of categories plus ordering +
+ Interval + + unit of measure plus zero point +
+ Log-interval + + exponent to define intervals +
+ Extensive + + ratio unit of measure
(additive rule applies) +
+ Cyclic + + ratio unit of measure plus length of cycle +
+ Derived + + ratio unit of measures
(formula of combination) +
+ Counts + + definition of objects counted +
+ Absolute + + type
(probability, proportion, etc.) +
+ + +
+
+ + + + + + + + + +

+ alle diese Skalen-Arten sind auf die Perspektive einer Messung / Beobachtung und wissenschaftlichen Deskription festgelegt; diesen Ansatz halte ich für zu eng — einen entscheidenden Hinweis gibt mir hier die Existenz Verktor-wertiger Funktionen ⟹ generell können wir mehr als nur ein »zahlenwert-artiges« Objekt haben ⟹ ich weite sofort auf die dahinter liegende Domain-Ontology aus. Jeder Ansatz einer universellen Klassifikation aller Parameter-Typen ist von Vornherein zum Scheitern verurteilt, denn man muß immer etwas über die dahinterliegende Bedeutung wissen... +

+

+ Was wir hier höchstens erzielen können ist eine Standard-Codierung strukturierter Daten, deren Interpretation dann Hilfestellung benötigt durch Domain-spezifische Erweiterungen. +

+ + +
+ +
+
@@ -82394,8 +82531,9 @@
- + + @@ -84175,10 +84313,12 @@ - + - + + + @@ -84298,6 +84438,10 @@ + + + + @@ -84582,7 +84726,8 @@ - + + @@ -84677,7 +84822,7 @@ - + @@ -84805,7 +84950,7 @@ - + @@ -85036,9 +85181,9 @@ - + - + @@ -85184,6 +85329,308 @@ + + + + + + + + +

+ Und zwar weil ich im Sinne flexibler Domain-Ontologien denke ⟶ wir brauchen »strukturierte Typen« (algebraische Datentypen) sowie diskrete symbolische Skalen, Summen- und Produkttypen. Die erheblichen Komplexitäten entstehen erwartungsgemäß dadurch, daß man das System dieser Skalen nicht a priori festlegen kann (denn dann hätte man sich implizit auf eine Domain-Ontologie festgelegt). Die Konsequenz ist, daß wir Skalen- und Strukturdefinitionen dynamisch, zur Laufzeit hinzufügen bzw. auf Projekt-Ebene festlegen müssen.... +

+ + +
+ + + + + + +

+ ...das heißt, eine ebenfalls durch strukturierte Daten vorgegebene Konfiguration möglicher Strukturen, einschließlich der Typ-IDs. +

+ + +
+
+ + + + + + +

+ ...letztlich werden diese strukturierten Parameter und Daten immer in Form eines algebraischen Datentyps darstellbar sein, wobei allerdings die »Bedeutung« aus dem Schema mit herangezogen werden muß; genauer gesagt, die Semantik kann nur innerhalb einer im Hintergrund vorausgesetzten Domain-Ontologie formal definiert werden und dann in eine Codierung übersetzt — insofern die Domain-Ontologien offen bleiben müssen, sehe ich nur den Weg, bestimmte Arten von Anfragen jeweils in die Implementierung auf Basis einer Domain-Ontologie zu delegieren (konkret: in ein Plug-in, welches auf der Domain-Ontology aufbaut). Die insgesamt möglichen Arten von Anfragen, zusammen mit der jeweiligen Codierungs-Regel, ergibt zusammen das effektive Schema, welches formale Transformationen und manipulationen der Daten ermöglicht +

+ + +
+
+ + + + +
+ + + + + + + + +

+ Die Domain selber gibt den Basis-Datentyp vor; innerhalb dessen gibt es einen minimalen und maximalen Wert +

+ + +
+
+ + + + + + +

+ Im Grunde geht es hier um die Unterscheidung ob »linear«, »logarithmisch« oder »diskret« +

+ + +
+
+ + + + + + + + + + + + + + + + + + +

+ wenn man dieses Muster streng nach den Regeln modelliert, dann wäre das ein algebraischer Datentyp mit einem Spezialfall-ENUM (Nominalskala), plus dem eigentlichen Zahlenwert, der aber nur bei bestimmten Nominal-Markern überhaupt betrachtet werden darf — also auch noch das Verhalten eines Summentyps +

+ + +
+
+ + + + + + +

+ die prinzipiell-korrekte Modellierung wäre aber eine Verfehlung der Aufgabe +

+ + +
+ + + + + +

+ Denn letztlich geht es darum, ein Zahlenwert-artiges, einfaches, unstrukturietes Objekt weiterzugeben und zu manipulieren — und zwar hinreichend effizient für den Rahmen von High-Performance-Code (heißt: nicht in der innersten Schleife, aber direkt daneben). Weder ist die Programmiersprache dafür gerüstet, algebraische Datentypen in diesem Kontext zu verarbeiten, noch sind die entsprechenden Mechanismen performant genug, um mit dem einfachen Normalfall einer »Zahl« mithalten zu können. Eine Modellierung dieses Musters als algebraischer Datentyp würde als unangemessene Prinzipienreiterei gewertet; das heißt, man muß schon verstehen, worauf es ankommt +

+ + +
+
+
+ + + + + + + + + + + + + + + + +

+ Das hier ist wirklich eine partielle thematische Überschneidung; denn Quantisierung ist auch unabhängig von Zeitangaben sehr relevant für Parameter, denn es kann alle möglichen Arten von Grids geben, und auch der Rundungs- bzw. Quantisierungsmechanismus könnte variabel sein. Die eigentliche Design-Frage jedoch ist, ob das auf dieser Ebene dargestellt werden muß, oder ob man das Thema komplett in die Automations-Provision hineinnimmt. Dafür, das Thema hier mit einer generischen Schnittstelle zu bedenken, würde eine Betrachtung sprechen, welche die »Parameter« als eine Codierungs-Basis versteht, deren Bedeutung durch ein Schema und eine dahinter liegende Ontologie festgelegt wird +

+ + +
+ + + +
+
+ + + + + + + + + + + + + + + + + + +

+ zudem: muß sicherstellen daß jede zuweisende Operation  diese Methode anwendet +

+ + +
+ + + + + +

+ Der Knackpunkt dabei sind die TypeHandler-Implementierungen, denn diese verwenden zunächst (nur) das lokal implementierte generische preClamp (was die Grenzen der BaseDomain durchsetzt und Bool-werte per Schwelle bildet) +

+ + +
+ + + + + + +

+ TypeHandler bezieht sich aber auf einen explizit und separat gegebenen Buffer, und konditioniert diesen nur im Hinblick auf den direkt spezifizierten Basis-Typ — wiewohl hier durchaus eine Unschärfe im Aufbau der Interfaces vorliegt, da ja in der conform() - Operation schon ein impliziter »Typ« angewendet wird, dessen Bedeutung nicht zweifelsfrei klar ist (man könnte geneigt sein, hier schon den vollständigen Parameter-Typ zu vermuten) +

+ + +
+
+ + + + + + +

+ ...denn es geht um die Durchsetzung einer Invariante für alle Werte »im« Parameter: sie müssen stets zum Parameter-Typ konform sein +

+ + +
+
+ + + + + + +

+ ...also jeweils wenn man sich einen Wert holt, was auch den »pull« der Automationsfunktion einschließt +

+ + +
+ +
+
+ + + + + + + + + + +

+ ...was aber als ein seltener Grenzfall zu betrachten ist, und normalerweise durch die übergeordnete Konfiguration ausgeschlossen werden soll. Für die geläufigen Szenarien gibt es zudem stets eine Regel, nach der konditioniert werden kann... +

+
    +
  • + wenn es sich zumindest um eine Intervallskala handelt, dann wird auf Maximum / Minimum gekappt +
  • +
  • + wenn es sich um eine Nominal / Ordinalskala handelt, und es einen Default-Wert gibt, dann wird dieser genommen +
  • +
  • + wenn es ein »INVALID« - Sentinel gibt, dann wird dieses genommen +
  • +
+

+ Somit bleiben eigentlich nur die Fälle einer speziellen Domain ohne Defaultwert — denn in diesem Fall gibt es keine übergeordnete Metrik, nach der interpoliert werden könnte, sondern ein Code, der nicht zur Skala gehört, ist ungültig und muß zurückgewiesen werden +

+ + +
+ +
+
+
+ + + + + + + + +

+ hier muß ggfs. eine Logarithmus / Exponential-Konvertierung stattfinden, möglicherweise auch eine Quantisierung +

+ + +
+ + + + + + + + + +

+ Grundsätzlich soll hier im Bereich der Scale nur eine Codierung  gehandhabt werden — es besteht die Gefahr, doch noch „durch die Hintertür“ eine universelle Wert-Ontologie einzuführen. +

+
    +
  • + es wird die Metrik des Parameters und der Automations-Provision mit herangezogen +
  • +
  • + ein optional vorhandener Neutralwert wird als Hinweis genommen: ein Neutralwert 1 ⟹ deutet auf einen multiplikativen Faktor hin +
  • +
+ + +
+ +
+
+
+
@@ -85252,6 +85699,9 @@ + + + @@ -85283,6 +85733,20 @@ + + + + + + + + + + + + + + @@ -85298,8 +85762,8 @@

- - + + @@ -85451,6 +85915,34 @@
+ + + + + + +

+ Da ist erst einmal das Problem daß hier eine separate Algebra definiert wurde; außerdem wird bei den Zeit-Entitäten auch eine Intention ausgedrückt (Offset, Duration, TimeSpan); und schließlich gilt es die Quantisierung und die Time-Codes zu beachten. Dieser Fall tritt definitiv auf und ist sehr relevant: es könnte einen animierbaren Delay geben, oder andere temporale Qualifikationen (Time-Trail, zeitliche Integration). +

+

+ Man könnte hier grundsätzich zwei ganz verschiedene Wege beschreiten: +

+
    +
  • + man könnte die Basis-Typen erweitern und die Diskrepanzen auf Ebene der Typ-Handler abfangen +
  • +
  • + denkbar wäre auch eine alternative Implementierung der Disposition (ParamData) notwendig, so daß man das Quantisierungs-Grid geeignet darstellen kann und u.U. sogar einen TimeSpan (zwei Datenwerte) noch in der Standard-Buffer-Storage unterbringt +
  • +
  • + man könnte stattdessen solche Parameter in die Kategorie der »komplexen Parameter« einordnen, die ja durchaus sehr häufig sein werden (z.B Farbwerte sind Vektoren); demnach wäre eine Zeit-Entität eben auch ein komplexer Wert, der auch ein Grid bzw. einen Timecode-Quantisierer impliziert +
  • +
+ + +
+ +
@@ -85471,7 +85963,7 @@ - + @@ -85480,6 +85972,108 @@

+ +
+
+ + + + + + + + + + + + + + +

+ Ganz ausdrücklich sollen hier auch komplex struktuierte Gebilde mit eingeschlossen sein, zu deren Interpretation eine Domain-Ontology mitwirken muß. +

+ + +
+
+ + + + + + +

+ Ich versuche dem Drang zu widerstehen, hier doch noch ein allgemeines Schema anzulegen; vielmehr wird konsequent die Handhabung der Daten per Callback-Funktor in den Nutz-Kontext zurück deflektiert. Der einzige zulässige Mechanismus ist die Bildung von »Prototypen« — wobei dann an die Stelle der Scale (des einfachen Parameters) hier ein Schema  tritt +

+ + +
+
+ + + + + + +

+ das ParamSet-Objekt ist grundsätzlich nur ein front-End-Handle, das auf anderweitig managed data verweist. +

+ + +
+
+ + + +
+ + + + + + +

+ Es ist sinnlos, beide unter einen gemeinsamen Typ zu subsumieren, aber der Schematismus für beide Fälle soll jeweils analog sein... +

+
    +
  • + ein kopierbares front-End-Handle +
  • +
  • + die Idee einer »Provision« mit Verknüpfbarkeit +
  • +
  • + ein impliziter Typ welcher Query-Funktionen bereitstellt +
  • +
+ + +
+
+
+ + + + + + + + + + + + + + + + +

+ Grundsätzlich gibt die jeweilige Verwendung einen Typ vor, und in diesen Typ wird transparent konvertiert; wenn aber »rein zufällig« der geforderte Typ dem nativen Typ entspricht, dann wird der optimierte Code-Pfad getriggert und der Zugriff geht an jedweder Indirektion vorbei +

+ + +
+