*************************************************************** * * * Komplexe Zahlen in VBA: benutzerdefinierte Datentypen * * * *************************************************************** Wir hatten gesehen, dass die Menge der eingebauten Excel- Funktionen und die Menge der eingebauten VBA-Funktionen deutlich unterschiedlich sind. Klickt man etwa auf das fx-Symbol um das Insert Function Dialog Fenster fuer Excel-Funktionen zu oeffnen, findet man unter der Kategorie Engineering eine Reihe von Funk- tionen (alle, die mit "Im" beginnen), die fuer das Rechnen mit komplexen Zahlen bestimmt sind. In VBA gibt es keine solchen Funktionen. Weiterhin hatten wir in Uebungsblatt3 gesehen, dass das Benutzen von Excel-Funktionen in VBA mit der Syntax Application.WorksheetFunction.excelfunctionname oder Excel.WorksheetFunction.excelfunctionname etwa um einen Faktor 20 langsamer ist als das Benutzen vergleich- barer (falls denn vorhanden) VBA-Funktionen. Da das Rechnen mit komplexen Zahlen nicht nur fuer die technischen Disziplinen sehr wichtig ist, sondern auch fuer die Finanzmathematik (so ist etwa der Preis einer Standard-Kauf-Option im Heston Stochastic Volatility Model gegeben durch ein komplexes Fourier-Integral), wollen wir in diesem Kapitel eine Funktionalitaet fuer komplexe Zahlen in VBA implementieren: Dazu definieren wir einen neuen "benutzerdefinierten" Datentyp mit Namen, etwa, cdouble (`complex double'), der aus zwei double's besteht, dem Real- und dem Imaginaerteil einer komplexen Zahl: Public Type cdouble re as double im as double End Type '-> take a quick look at VBA-Hilfe for type-statement und muessen dann Funktionen fuer das Rechnen mit solchen cdouble's bereitstellen, also fuer die komplexe Addition, Subtraktion, Multiplikation, Division, die komplexe Exponentialfunktion und eventuell weitere komplexe Funktion (sqrt,log,...). Die Syntax fuer die komplexe Addition, als Namen waehlen wir etwa "cplus", wuerde dann so aussehen: Function cplus(z As cdouble, w As cdouble) As cdouble Dim resre As Double 'res for result Dim resim As Double resre = z.re + w.re resim = z.im + w.im cplus.re = resre cplus.im = resim End Function Weiterhin brauchen wir eine Funktion, die es ermoeglicht, jede reelle Zahl x als komplexe Zahl z=x+i*0 aufzufassen, etwa: Function cdouble(x As Double, y As Double) As cdouble cdouble.re = x cdouble.im = y End Function Die Wahl von "cdouble" als Funktionsname scheint keine Probleme zu verursachen, ansonsten wuerde man eine solche Funktion vielleicht "complex" nennen wollen. Nachdem wir diese Funktionen implementiert haben, wollen wir die Funktionalitaet testen, indem wir ein bekanntes Fourier-Integral numerisch berechnen. Es gilt folgende Formel ("die Fourier- Transformation einer Gauss-Funktion ist eine Gauss-Funktion"): int_{-infty}^{infty} exp(ikx) exp(-alpha x^2/2) dx/sqrt(2 pi) = 1/sqrt(alpha) exp(-1/alpha * k^2/2) (1) Dabei soll die Formel (1) einmal mit der neuen VBA-Funktionalitaet ueberprueft werden und zum anderen mit Hilfe der "Im" Excel-Formeln, die als Worksheet-Functions zur Verfuegung stehen. Die Rechenzeiten sollen in beiden Faellen mit ausgegeben werden. Dabei wollen wir die Formel (1) fuer folgende Werte von k berechnen und das Resultat (exaktes Reultat, Real- und Imaginaerteil des numerischen Resultats, der Riemannschen Summe) auf das Excel-sheet schreiben: k in {-5.0,-4.9,-4.8,...,+4.8,+4.9,+5.0} . Fuer dx waehlen wir etwa 1/1000 und das Intervall (-infty,infty) approximieren wir etwa durch (-10,10).