Hardcover physics class notes.

March 13, 2021 math and physics play , , , , , , , , , , , , , ,

Amazon’s kindle direct publishing invited me to their hardcover trial program, and I’ve now made hardcover versions available of most of my interesting physics notes compilations:

Instead of making hardover versions of my classical mechanics, antenna theory, and electromagnetic theory notes, I have unpublished the paperback versions. These are low quality notes, and I don’t want more people to waste money on them (some have.) The free PDFs of all those notes are still available.

My geometric algebra book is also available in both paperback and hardcover (black and white). I’ve unpublished the color version, as it has a much higher print cost, and I thought it was too confusing to have all the permutations of black-and-white/color and paperback/hardcover.

Debugging a C coding error from an XPLINK assembly listing.

March 12, 2021 C/C++ development and debugging., Mainframe , , , , , , ,

There are at least two\({}^1\) z/OS C calling conventions, the traditional “LE” OSLINK calling convention, and the newer\({}^2\) XPLINK convention.  In the LE calling convention, parameters aren’t passed in registers, but in an array pointed to by R1.  Here’s an example of an OSLINK call to strtof():

*  float strtof(const char *nptr, char **endptr);
LA       r0,ep(,r13,408)
LA       r2,buf(,r13,280)
LA       r4,#wtemp_1(,r13,416)
L        r15,=V(STRTOF)(,r3,4)
LA       r1,#MX_TEMP3(,r13,224)
ST       r4,#MX_TEMP3(,r13,224)
ST       r2,#MX_TEMP3(,r13,228)
ST       r0,#MX_TEMP3(,r13,232)
BASR     r14,r15
LD       f0,#wtemp_1(,r13,416)

R1 is pointed to r13 + 224 (a location on the stack). If the original call was:

float f = strtof( mystring, &err );

The compiler has internally translated it into something of the form:

STRTOF( &f, mystring, &err );

where all of {&f, mystring, &err} are stuffed into the memory starting at the 224(R13) location. Afterwards the value has to be loaded from memory into a floating point register (F0) so that it can be used.  Compare this to a Linux strtof() call:

* char * e = 0;
* float x = strtof( "1.0", &e );
  400b74:       mov    $0x400ef8,%edi       ; first param is address of "1.0"
  400b79:       movq   $0x0,0x8(%rsp)       ; e = 0;
  400b82:       lea    0x8(%rsp),%rsi       ; second param is &e
  400b87:       callq  400810 <strtof@plt>  ; call the function, returning a value in %xmm0

Here the input parameters are RDI, RSI, and the output is XMM0. Nice and simple. Since XPLINK was designed for C code, we expect it to be more sensible. Let’s see what an XPLINK call looks like. Here’s a call to fmodf:

*      float r = fmodf( 10.0f, 3.0f );
            LD       f0,+CONSTANT_AREA(,r9,184)
            LD       f2,+CONSTANT_AREA(,r9,192)
            L        r7,#Save_ADA_Ptr_9(,r4,2052)
            L        r6,=A(__fmodf)(,r7,76)
            L        r5,=A(__fmodf)(,r7,72)
            BASR     r7,r6
            NOP      9
            LDR      f2,f0
            STE      f2,r(,r4,2144)
*
*      printf( "fmodf: %g\n", (double)r );

There are some curious details that would have to be explored to understand the code above (why f0, f2, and not f0,f1?), however, the short story is that all the input and output values in (floating point) registers.

The mystery that led me to looking at this was a malfunctioning call to strtof:

*      float x = strtof( "1.0q", &e );
            LA       r2,e(,r4,2144)
            L        r7,#Save_ADA_Ptr_12(,r4,2052)
            L        r6,=A(strtof)(,r7,4)
            L        r5,=A(strtof)(,r7,0)
            LA       r1,+CONSTANT_AREA(,r9,20)
            BASR     r7,r6
            NOP      17
            LR       r0,r3
            CEFR     f2,r0
            STE      f2,x(,r4,2148)
*
*      printf( "strtof: v: %g\n", x );

The CEFR instruction converts an integer to a (hfp32) floating point representation, so we appear to have strtof returning it’s value in R3, which is an integer register. That then gets copied into R0, and finally into F2 (and after that into a stack spill location before the printf call.) I scratched my head about this code for quite a while, trying to figure out if the compiler had some mysterious way to make this work that I wasn’t figuring out. Eventually, I clued in. I’m so used to using a C++ compiler that I forgot about the old style implicit int return for an unprototyped function. But I had included <stdlib.h> in this code, so strtof should have been prototyped? However, the Language Runtime reference specifies that on z/OS you need an additional define to have strtof visible:

#define _ISOC99_SOURCE
#include <stdlib.h>

Without the additional define, the call to strtof() is as if it was prototyped as:

int strtof( const char *, char ** );

My expectation is that with such a correction, the call to strtof() should return it’s value in f0, just like fmodf() does. The result should also not be garbage!

 

Footnotes:

  1.  There is also a “metal” compiler and probably a different calling convention to go with that.  I don’t know how metal differs from XPLINK.
  2. Newer in the lifetime of the mainframe means circa 2001, which is bleeding edge given the speed that mainframe development moves.

Hardcover edition of Geometric Algebra for Electrical Engineers.

February 27, 2021 Uncategorized , , , ,

I was invited to Kindle Direct Publishing‘s hardcover beta program, and have made my geometric algebra book available in black and white hardcover.

As always, the PDF, leanpub edition, and latex sources are also available.

I thought that it was too confusing to have color and black-and-white editions of the book (color has a significantly higher printing cost), so I have unpublished the color editions of the book (softcover, and hardcover). There is one copy of the color edition left, and once that is sold, it will show as out of print.

A better 3D generalization of the Mandelbrot set.

February 9, 2021 math and physics play , , , , , , ,

I’ve been exploring 3D generalizations of the Mandelbrot set:

The iterative equation for the Mandelbrot set can be written in vector form ([1]) as:
\begin{equation}
\begin{aligned}
\Bz
&\rightarrow
\Bz \Be_1 \Bz + \Bc \\
&=
\Bz \lr{ \Be_1 \cdot \Bz }
+
\Bz \cdot \lr{ \Be_1 \wedge \Bz }
+ \Bc \\
&=
2 \Bz \lr{ \Be_1 \cdot \Bz }

\Bz^2\, \Be_1
+ \Bc
\end{aligned}
\end{equation}
Plotting this in 3D was an interesting challenge, but showed that the Mandelbrot set expressed above has rotational symmetry about the x-axis, which is kind of boring.

If all we require for a 3D fractal is to iterate a vector equation that is (presumably) at least quadratic, then we have lots of options. Here’s the first one that comes to mind:
\begin{equation}
\begin{aligned}
\Bz
&\rightarrow
\gpgradeone{ \Ba \Bz \Bb \Bz \Bc } + \Bd \\
&=
\lr{ \Ba \cdot \Bz } \lr{ \Bz \cross \lr{ \Bc \cross \Bz } }
+
\lr{ \Ba \cross \Bz } \lr{ \Bz \cdot \lr{ \Bc \cross \Bz } }
+ \Bd
.
\end{aligned}
\end{equation}
where we iterate starting, as usual with \( \Bz = 0 \) where \( \Bd \) is the point of interest to test for inclusion in the set. I tried this with
\begin{equation}\label{eqn:mandel3:n}
\begin{aligned}
\Ba &= (1,1,1) \\
\Bb &= (1,0,0) \\
\Bc &= (1,-1,0).
\end{aligned}
\end{equation}
Here are some slice plots at various values of z

and an animation of the slices with respect to the z-axis:

Here are a couple snapshots from a 3D Paraview rendering of a netCDF dataset of all the escape time values

Data collection and image creation used commit b042acf6ab7a5ba09865490b3f1fedaf0bd6e773 from my Mandelbrot generalization experimentation repository.

References

[1] L. Dorst, D. Fontijne, and S. Mann. Geometric Algebra for Computer Science. Morgan Kaufmann, San Francisco, 2007.

Slicing of the 3D Mandelbrot set, and analysis.

February 8, 2021 math and physics play , , , , , , ,

Some slices.

As followup to:

here is a bit more experimentation with Paraview slice filtering. This time I saved all the point data with the escape time counts, and rendered it with a few different contours

The default slice filter places the plane in the x-y orientation:

but we can also tilt it in the Paraview render UI

and suppress the contour view to see just the slice

As a very GUI challenged user, I don’t find the interface particularly intuitive, but have at least figured out this one particular slicing task, which is kind of cool.  It’s impressive that the UI can drive interesting computational tasks without having to regenerate or reload any of the raw data itself.  This time I was using the MacOSX Paraview client, which is nicer looking than the Windows version, but has some weird glitches in the file dialogues.

Analysis.

The graphing play above shows some apparent rotational symmetry our vector equivalent to the Mandelbrot equation
\begin{equation}
\Bx \rightarrow \Bx \Be_1 \Bx + \Bc.
\end{equation}
It was not clear to me if this symmetry existed, as there were artifacts in the plots that made it appear that there was irregularity. However, some thought shows that this irregularity is strictly due to sampling error, and perhaps also due to limitations in the plotting software, as such an uneven surface is probably tricky to deal with.

To see this, here are the first few iterations of the Mandlebrot sequence for an arbitary starting vector \( \Bc \).
\begin{equation}
\begin{aligned}
\Bx_0 &= \Bc \\
\Bx_1 &= \Bc \Be_1 \Bc + \Bc \\
\Bx_2 &= \lr{ \Bc \Be_1 \Bc + \Bc } \Be_1 \lr{ \Bc \Be_1 \Bc + \Bc } + \Bc \Be_1 \Bc + \Bc.
\end{aligned}
\end{equation}

Now, what happens when we rotate the starting vector \( \Bc \) in the \( y-z \) plane. The rotor for such a rotation is
\begin{equation}
R = \exp\lr{ e_{23} \theta/2 },
\end{equation}
where
\begin{equation}
\Bc \rightarrow R \Bc \tilde{R}.
\end{equation}
Observe that if \( \Bc \) is parallel to the x-axis, then this rotation leaves the starting point invariant, as \( \Be_1 \) commutes with \( R \). That is
\begin{equation}
R \Be_1 \tilde{R} =
\Be_1 R \tilde{R} = \Be_1.
\end{equation}
Let \( \Bc’ = R \Bc \tilde{R} \), so that
\begin{equation}
\Bx_0′ = R \Bc \tilde{R} = R \Bx_0 \tilde{R} .
\end{equation}
\begin{equation}
\begin{aligned}
\Bx_1′
&= R \Bc \tilde{R} \Be_1 R \Bc \tilde{R} + R \Bc \tilde{R} \\
&= R \Bc \Be_1 \Bc \tilde{R} + R \Bc \tilde{R} \\
&= R \lr{ \Bc \Be_1 \Bc R + \Bc } \tilde{R} \\
&= R \Bx_1 \tilde{R}.
\end{aligned}
\end{equation}
\begin{equation}\label{eqn:m2:n}
\begin{aligned}
\Bx_2′
&= \Bx_1′ \Be_1 \Bx_1′ + \Bc’ \\
&= R \Bx_1 \tilde{R} \Be_1 R \Bx_1 \tilde{R} + R \Bc \tilde{R} \\
&= R \Bx_1 \Be_1 \Bx_1 \tilde{R} + R \Bc \tilde{R} \\
&= R \lr{ \Bx_1 \Be_1 \Bx_1 + \Bc } \tilde{R} \\
&= R \Bx_2 \tilde{R}.
\end{aligned}
\end{equation}

The pattern is clear. If we rotate the starting point in the y-z plane, iterating the Mandelbrot sequence results in precisely the same rotation of the x-y plane Mandelbrot sequence. So the apparent rotational symmetry in the 3D iteration of the Mandelbrot vector equation is exactly that. This is an unfortunately boring 3D fractal. All of the interesting fractal nature occurs in the 2D plane, and the rest is just a consequence of rotating that image around the x-axis. We get some interesting fractal artifacts if we slice the rotated Mandelbrot image.