DMUG-Archiv 2000

Frühere   Chronologischer Index   Spätere
Vorherige   Thematischer Index   Nächste

Re: Objekte und Zugriffs-Funktionen

-------------------------------------------------------
directly from my SGI Octane with IRIX 6.5
-------------------------------------------------------
Hallo,

bitmap-Formate sind generell ein kleiner Alptraum. Jedes Betriebssystem
hat
sein eigenes, jedes Graphik Program nat"urlich auch. Wobei selbst
l"angst 
verstorbene Betriebssysteme (OS/2 Bitmaps, GEM Format der Ataris) und 
Firmen (ZSoft & PCX) ihre Zombies hinterlassen haben.
Eine vern"unftige Dokumentation aller bitmap-Formate und ihrer
Spezialit"aten
(Paletten, Bittiefe, TIFF's mit float ...) ist ziemlich illusorisch.
Dass die Referenz nicht alle Pattern f"ur Raster[] auff"uhrt ist jedoch 
eindeutig ein Fehler.

Ich h"atte es bei Mathematica gern gesehen, wenn man zumindest die
Paletten
rausgeworfen h"atte und einheitlich nur RGBColor/GrayLevel-Raster[]
Dateien
erzeugt h"atte. Dann h"atte es auch so sch"one Funktionen wie
GetRedChannel[] geben
k"onnen. Die Paletten in der ColorFunction verderben das aber, weil man
dort
den Rot-Kanal eben aus der Manipulation der Palette und *nicht* aus der
Bildmatrix
erh"alt. Nat"urlich gibt es dann immer noch Leute die CMYK Farben in ein
TIFF mit
Alpha-Kanal stecken, was nicht f"ur die auschliessliche Verwendung des
RGB-Models
f"ur die Farben spricht.

Ich h"atte es auch lieber gesehen, dass *keine* Graphics[] Objekte
um die Importierten Daten gelegt worden w"aren. Dass h"atte zwar
Probleme mit dem
Aspekt-Verh"altnis gegeben aber man h"atte sich nicht durch die
Graphics[Raster[__],___]
Struktur k"ampfen m"ussen. Die jetzige Variante ist eindeutig darauf
ausgelegt
das Bild nur zu Importieren und Anzuzeigen, das geht ganz prima. Die
Bildbearbeitung wird
dadurch aber unn"otig erschwert und als Bitmap Betrachter allein wird
wohl niemand
Mathematica verwenden. Sondern -- wer ein Bild in Mathematica Importiert
*will* es
bearbeiten und vielleicht am Ende auch mal anzeigen.

Nix gegen imperative Programmierung, feine Sache das. Klar kan man mit
img[[1,1]] sich die
Raster-Matrix holen und mit img[[1,1,i,j]] die einzelne Pixel. Da
Mathematica 
intern tats"achlich Arrays verwendet geht das sogar leidlich schnell.
Das unangenhme
daran ist nur, der Interpreter muss immer die Feld-Grenzen testen. Mit
einem Map[_,img[[1,1]],{2}]
entf"allt das und bei so einfachen Aktionen wie dem blo"sen Lesen nehmen
die Index Tests
mehr Zeit in Anspruch als der Rest.
"Schnell" sind solche Zugriffe in einem compilierten Programm das mit
einem
Core-Dump abschmiert wenn man den falschen Index erwischt. Ich habe
Programme
mit Matrix-Zugriffen "uber Funktionen gesehen den 70 % ihrer Rechenzeit
mit
Index-checks zugebracht haben. Diese Tests m"ussen aber bei einem
Interpreter sein,
anderefalls gibts bei jedem kleinen Fehler der Nutzers Abst"urze statt
Fehlermeldungen.

Das feine imperative Programm das dauernd img[[1,1,i+1,j-4]] enth"alt
ist 
auch kein  Wunder an "Ubersichtlichkeit, wer nach zwei Wochen noch weiss
das
img[[1,1,i,j,2]] bei einem RGB Bild den gr"unen Kanal liefert ist ein 
"real programmer" der auch einen Hexdump "uber Telephon debuggt, aber
wer kann
das heute noch -- in einer Zeit wo die Leute nicht mal mehr Lochkarten
haben.

ListConvolve[] *ist* wesentlich scheller als alles andere was man sich
ausdenken kann.
Schon weil es eine build-in Funktion ist. Man kann es noch mit

LaplaceFilter[bm_?MatrixQ]:=
-4*bm+RotateLeft[bm]+RotateRight[bm]+RotateLeft /@ bm + RotateRight /@
bm 

probieren wenn die 4 Nullen wirklich st"oren (erkl"aren Sie mir bitte
nicht 
was ich da mache) wenn man blo"s eine Kanal hat oder aber alle Kan"ale 
transformieren will. Jedenfalls braucht man keinen expliziten Zugriff
auf die
Matrixelemente, man muss nicht wissen wie gross die Bitmap ist, man muss
nicht mal
wissen ob man in bm eine Matrix von Grauwerten oder RGB-Farben
"ubergeben hat. 
In einem imperative Programm sammelt man erst die Dimensionen, erzeugt
eine Doppelschleife
l"asst jeden Index-Zugriff testen und wartet halt ein bischen l"anger. 

Nat"urlich testet Show[] seine Argumente. Im Idealfall hat es lauter
Regeln

Show[gr_Graphics3D,opts___?OptionQ]:= ...

Show[gr_Graphics,opts___?OptionQ]:= ...

Show[gr_GraphicsArray,opts___?OptionQ]:= ...

...

Show[unknow_,opts___?OptionQ]:= Message[___];  (* lustige Fehlermeldung
*)

Ich w"urde auch bei der Bitmap- Bearbeitung eine jede Funktion mit den
Regeln

someBitmapFunction[Graphics[Raster[m_,___],___]]:= someBitmapFunction[m]
someBitmapFunction[Raster[m_,___]]:=someBitmapFunction[m]

versehen. Nur das Pattern f"ur someBitmapFunction[m_?MatrixQ] 
w"urde dann tats"achlich irgendwas machen.

Wann eine Elegante Vormulierung auch schneller ist kann 
h"angt vom Kontext ab und n"at"urlich
von den Problem. Im Einzelfall muss man immer 
testen & messen. Man kann sich dann immer noch
"uberlegen, ob der Geschwidigkeitsgewinn die 
Sache Wert ist einen absolut unlesbaren
Code zu produzieren der eine halbe Millisekunde 
schneller ist oder einen sch"onen eleganten
Code der auch nach einem halben Jahr noch verst"andlich ist.


Gruss
  Jens

woysch |u| wrote:
> 
> --------------------------------------------------------------------------------
> 
>   directly from my Sun workstation ULTRA 1 under SunOS 5.5.1 and CDE V 1.0.2
> 
> --------------------------------------------------------------------------------
> 
> Sehr geehrter Herr Kuska,                  Stuttgart, den 6. + 7. Februar 2000
> 
> vielen Dank, dass Sie sich die Muehe machten, so ausfuehrlich auf meine DMUG-
> Anfrage vom Mon Jan 31 16:31:50 2000 zum Thema
> 
>    Objekte und Zugriffsfunktionen in Mathematica
> 
> mit einer eMail vom Mon Jan 31 20:11:06 2000 zu antworten.
> 
> Zu den Grundlagen von Mathematica
> ---------------------------------
> 
> Soweit ich das sehe, sind einige der wichtigsten Grundlagen von Mathematica :
> 
>      - Verwendung von Listenstrukturen fuer alle Objekte
> 
>      - Gleichartige Darstellung von Daten und Funktionen
> 
>      - Hierachische Schachtelbarkeit von Listen
> 
> Auf dieser Basis, die stark an LISP erinnert, sind offensichtlich sowohl
> 
>      - prozedurale Programmierung   und
> 
>      - regelbasierte Programmierung
> 
> gleichermassen moeglich.
> 
> Dabei erinnert die regelbasierte Programmierung an PROLOG und ist fuer jeden,
> der von "normalen" Programmiersprachen herkommt, eine hoechst gewoehnungs-
> beduerftige Sache.
> 
> Damit gelingen aber sehr praegnante und elegante Loesungen - das haben Sie
> ja eindruecklich demonstriert.
> 
> Zur regelbasierten Programmierung
> ---------------------------------
> 
> Zur Realisierung von Fallunterscheidungen mit Hilfe von regelbasierter Program-
> mierung merkte ich mir frueher, dass man zuerst die Regel fuer den speziellsten
> Fall aufschreibt, und dann schrittweise zu weniger einschraenkenden Faellen
> weitergeht.
> 
> So werden zuerst die Sonderfaelle herausgefiltert, bis man dann zur Behandlung
> des allgemeinen Falles kommt.
> 
> Der imperative und der regelbasierte Programmierzugang zusammen ergaenzen ein-
> ander in Mathematica.
> 
> Die Einheitlichkeit des Konzeptes von Mathematica und die Tatsache, dass sie
> auch unter widrigen Umstaenden durchgehalten wird, geben Mathematica ein echtes
> Geruest, das die Vielseitigkeit von Mathematica wirklich tragen kann.
> 
> 
> Dokumentation von Mathematica
> -----------------------------
> 
> Persoenlich verwende ich - ganz einfach aus Zeitgruenden - als Dokumentation zu
> Mathematica ( in dieser Reihenfolge ) :
> 
>      - Den ins Programm integrierten Mathematica-Help-Browser
> 
>      - Das Mathematica-Buch
> 
>      - Sekundaer-Literatur .
> 
> Zur direkten Mathematica-Dokumentation moechte ich bemerken, dass sie sehr
> beispielorientiert ist, und man sie erst zu lesen lernen muss. Dazu unten
> noch ein paar Bemerkungen.
> 
> Es fehlt mir ein wenig eine kurze, an der Systematik orientierte Einfuehrung,
> die auch die Zusammenhaenge der verschiedenen Objekte explizit und knapp dar-
> stellt.
> 
> Vielleicht koennte man sich eine Art von Zusammenhangsgraphen vorstellen,
> die z.B. Graphics mit Raster in den verschiedenen Variationen beschreibt.
> 
> Das Zugriffsproblem auf Rasterdaten
> -----------------------------------
> 
> Ausgangspunkt dieser Diskussion war ein Zugriffsproblem auf Raster-Graphik-
> Daten.
> 
> Unter dem Suchbegriff _Raster_ finden sich die folgenden Angaben :
> 
>       - Raster[ { { a11, a12, ... }, ... }         ]
>       - Raster[ array, ColorFunction -> f          ]
>       - Raster[ array, ColorFunction -> Hue        ]
>       - Raster[ array, {{xmin, ymin},{xmax, ymax}} ]
>       - Raster[ array, rect, {zmin, zmax}          ]  .
> 
> Das ist ja _auch_ eine implizite Struktur-Beschreibung der moeglichen Alter-
> nativen - das habe ich mir beim Nachdenken ueber Ihre Antwort wieder so richtig
> klargemacht !
> 
> Und dieses Wissen kann man ausnutzen; keine Frage.
> 
> Das Graphik-Beispielproblem
> ---------------------------
> 
> Diese Ueberlegungen von oben sind nach meinem Verstaendnis sozusagen die, die
> Sie anstellten zu der Formulierung :
> 
>       - gr /. Graphics[Raster[m_,___],___] :> m .
> 
> Sie greifen mit dieser verzoegerten Ersetzungsregel auf genau die Graphikdaten
> ( die Matrix "m_" ) zu, mit denen dann weitergearbeitet werden soll.
> 
> Eine aeusserst knappe Formulierung, in der zudem alle weiteren Teile von Raster
> und von Graphics wegen "___" wirklich voellig offen bleiben !
> 
> Auch die Matrix ist ja nirgendwo als solche definiert.
> 
> Als Alternative fuehren Sie an :
> 
>       - First /@ Cases[gr,_Raster,Infinity]  .
> 
> Hier mappt man die Auswahl Cases auf das Objekt bzw. den Ausdruck gr, wendet es
> auf alle Ausdruecke darin mit dem Kopf _Raster an, und das fuer eine unbegrenzte
> Zahl von Ebenen. Hier steckt das Wissen, dass die _relevanten_ Daten der _erste_
> _Ausdruck_ von Raster sind, bereits in der Verwendung der Funktion First.
> 
> Man _kennt_ die Konstruktion des zu verarbeitenden Objektes.
> 
> Implementierung von Matrizen und Matrizen-Zugriffen
> ---------------------------------------------------
> 
> Matrizen habe eine einfache, ihnen eigene Struktur. In anderen Programmier-
> sprachen verwendet man fuer den effizienten Zugriff auf Elemente von Matrizen
> oft mehrfache Zeigerrechnungen, bis man an der Adresse des entsprechenden
> Matrizen-Elementes angekommen ist.
> 
> Deswegen ist der explizite Zugriff auf Matrix-Elemente normalerweise eher
> "nicht teuer", was Zugriffszeit und Kodeaufwand betrifft. Das kann allerdings
> in der Mathematica-Implementierung aber anders sein.
> 
> Leider weiss ich nichts ueber die Implementierung von ( speziellen ) Listen,
> den zugehoerigen Zugriffsoperationen und auch den Listenverknuepfungen in
> Mathematica.
> 
> Man koennte sich denken, dass Verweise auf Listenelemente solange ohne Kopieren
> dieser Elemente auskommen koennten, wie Mehrfach-Verweise auf ein Listenelement
> keine unterschiedlichen Daten meinen.
> 
> Oder anders gesagt, bezogene Listenelemente werden _erst dann_ kopiert, wenn sie
> sich durch Bearbeitung durch Funktionen aendern _muessen_ .
> 
> Sofern das so ist, sind natuerlich Bezuege auch auf komplexe Strukturen sehr
> "billig", solange sie _ohne Veraenderung_ der Daten auskommen.
> 
> Laplace-Operation auf dem Rot-Kanal eines RGB-Bildes
> ----------------------------------------------------
> 
> Allerdings bedeutet eine _elegante Notation_ einer Listenoperation noch lange
> keine effiziente Berechnung :
> 
>     ListConvolve[{{ 0, 1, 0},
>                   { 1,-4, 1},
>                   { 0, 1, 0}}, bitmap /. RGBColor[r_,_,_]:> r]  .
> 
> Es koennte so sein, dass hier jeweils drei nebeneinanderliegende Listenelemente
> quasi _gemeinsam gelesen_ werden und quasi _gemeinsam_ auf ein Element einer
> anderen Liste wirken. Dann _kann_ das eine effiziente Berechnung sein.
> 
> Aus meiner Sicht ist das offen, was da eine _effiziente_ Formulierung ist.
> 
> Allerdings gebe ich zu, dass dieses ListConvolve eine pfiffige Formulierung ist.
> 
> Schliesslich werden hier in der ersten Matrix immerhin vier Nullen bei insgesamt
> 9 Koeffizienten mitgefuehrt. Diese Nullen tragen ja nichts zum Ergebnis bei.
> 
> Sie werden wohl nur deswegen mitgefuehrt, weil damit drei gleichartige Matrix-
> zeilen vorliegen. Ich kann mir durchaus vorstellen, dass so die Berechnung
> regulaerer wird und dadurch effizienter. Aber ob es sich dann auch lohnt, das
> weiss ich nicht !
> 
> Fuer eine Erklaerung, unter welchen Bedingungen elegante regelbasierte
> Formulierungen auch zu effizienten Formulierungen fuehren, waere ich
> durchaus dankbar !
> 
> Show[ datum ]
> -------------
> 
> Besser haette ich wohl Show[ graphicsObject ] schreiben sollen.
> 
> Damit waere klarer gewesen, dass ich meine, Show[ .. ] behandelt wenigstens die
> verschiedenen Graphik-Objekte korrekt, ohne dass man Show[ .. ] mitteilen muss,
> um _welchen_ Graphik-Typ es sich handelt und _wie er aufgebaut_ ist.
> 
> Dass Show[ Date ] eine Fehlermeldung bringt und kein sinnloses "Ergebnis",
> verstehe ich durchaus als erfreulich.
> 
> Show[ .. ] macht somit eine Art Ueberpruefung der uebergebenen Objekte !
> 
> Rueckmeldungen, Korrekturen, Kritik
> --------------  -----------  ------
> 
> Fuer Rueckmeldungen jeder Art bin ich dankbar - schliesslich kann man ja daraus
> nur etwas lernen !
> 
> Ob ich noch einmal Argumente und Ueberlegungen fuer eine weitere Antwort finde,
> weiss ich jetzt natuerlich noch nicht !
>


Verweise:
Frühere   Chronologischer Index   Spätere
Vorherige   Thematischer Index   Nächste

DMUG DMUG-Archiv, http://www.mathematica.ch/archiv.html