complex numbers

A less evil COBOL toy complex number library

December 29, 2023 COBOL , , , , , , , , , ,

In a previous post ‘The evil of COBOL: everything is in global variables’, I discussed the implementation of a toy complex number library in COBOL.

That example code was a single module, having one paragraph for each function. I used a naming convention to work around the fact that COBOL functions (paragraphs) are completely braindead and have no input nor output parameters, and all such functions in a given loadmodule have access to all the variables of the entire program.

Perhaps you try to call me on my claim that COBOL doesn’t have parameters, nor does it have return values.  That’s true if you consider COBOL paragraphs to be the equivalent to functions.  I’ve heard paragraphs described as not-really-functions, and there’s some truth to that, especially since you can do a PERFORM range that executes a set of paragraphs, and there can be non-intuitive control flow transfers between paragraphs of such a range of execution, that is entirely non-function like.

There is one circumstance where COBOL parameters can be found.  It is actually possible to have both input and output parameters in COBOL, but it can only be done at a program level (i.e.: int main( int argc, char ** )). So, you can write a less braindead COBOL library, with a set of meaningful input and output parameters for each function, by using CALL instead of PERFORM, and a whole set of external programs, one for each of the operations that is desired. With that in mind, I’ve reworked my COBOL complex number toy library to use this program-level organization.  This is still a toy library implementation, but serves to illustrate the ideas.  The previous paragraph implementation can be found in the same repository, in the ../paragraphs-as-library/ directory.

Here are some examples of the functions in this little library, and examples of calls to them.

Multiply code:

And here’s a call to it:

Notice that I’ve opted to use dynamic calls to the COBOL functions, using a copybook that lists all the possible function names:

This frees me from the constraint of having to use inscrutable 8-character function names, which will get confusing as the library grows.

Like everything in COBOL, the verbosity makes it fairly unreadable, but refactoring all paragraphs into external programs, does make the calling code, and even the library functions themselves, much more readable.  It still takes 49 lines of code, to initialize two complex numbers, multiply them and display them to stdout.

Compare to the same thing in C++, which is 18 lines for a grow-your-own complex implementation with multiply:

#include <iostream>

struct complex{
   double re_;
   double im_;
};

complex mult(const complex & a, const complex & b) {
   // (a + b i)(c + d i) = a c - b d + i( b c + a d) 
   return complex{ a.re_ * b.re_ - a.im_ * b.im_,
                   a.im_ * b.re_ + a.re_ * b.im_ };
}

int main()
{
   complex a{1,2};
   complex b{3,4};
   complex c = mult(a, b);
   std::cout << "c = " << c.re_ << " +(" << c.im_ << ") I\n";

   return 0;
}

and only 11 lines if we use the standard library complex implementation:

#include <iostream>
#include <complex>

using complex = std::complex<double>;

int main() 
{  
   complex a{1,2}; 
   complex b{3,4};
   complex c = a * b;
   std::cout << "c = " << c << "\n";

   return 0;
}

Basically, we have one line for each operation: init, init, multiply, display, and all the rest is one-time fluff (the includes, main decl, return, …)

It turns out that the so-called OBJECT oriented COBOL extension to the language (circa Y2K), is basically a packaging of external-style-programs into collections that are class prefixed, just as I’ve done above.  This provides the capability for information hiding, and allows functions to have parameters and return values.  However, this doesn’t try to rectify the fundamental failure of the COBOL language: everything has to be in a global variable.  This language extension appears to be a hack that may have been done primarily for Java integration, which is probably why nobody uses it.  You just can’t take the dinosaur out of COBOL.

Sadly, it didn’t take people long to figure out that it’s incredibly dumb to require all variables to be global.  Even PL/I, which is 59 years old at the time I write this (only five years younger than COBOL), got it right.  They added parameters and return values to functions, and allow functions to have variables that are limited to that scope.  PL/I probably went too far, and added lots of features that are also braindead (like the PL/I macro preprocessor), but the basic language is at least sane.  It’s interesting that COBOL never evolved.  A language like C++ may have evolved too much, and still is, but the most flagrant design flaw in the COBOL language has been there since inception, despite every other language in the world figuring out that sort of stupidity should not be propagated.

Note that I work on the development of a COBOL and PL/I compilation stack.  I really like my work, which is challenging and great fun, and I work with awesome people. That doesn’t stop me from acknowledging that COBOL is a language spawned in hell by Satan. I can love my work, which provides tools for customers allowing them to develop, maintain and debug COBOL code, but also have great pity and remorse for those customers, having inherited ancient code built with an ancient language, and having no easy migration path away from that language.

The evil of COBOL: everything is in global variables

December 7, 2023 COBOL , , , , , , ,

COBOL does not have stack variables.  Everything is a global variable.  There is a loose equivalent of a function, called a paragraph, which can be called using a PERFORM statement, but a paragraph does not have any input or output variables, and no return code, so if you want it to behave like a function, you have to construct some sort of complicated naming convention using your global variables.

I’ve seen real customer COBOL programs with many thousands of global variables.  A production COBOL program is usually a giant sequence of MOVEs, MOVE A TO B, MOVE B TO C, MOVE C TO D, MOVE D TO E, … with various PERFORMs or GOTOs, or other things in between.  If you find that your variable has a bad value in it, that is probably because it has been copied from something that was copied from something, that was copied from something, that’s the output of something else, that was copied from something, 9 or 10 times.

I was toying around with the idea of coding up a COBOL implementation of 2D Euclidean geometric algebra, just as a joke, as it is surely the worst language in the world.  Yes, I work on a COBOL compiler project. The project is a lot of fun, and the people I work with are awesome, but I don’t have to like the language.

If I was to implement this simplest geometric algebra in COBOL, the logical starting place for that would be to implement complex numbers in COBOL first.  That is because we can use a pair of complex numbers to implement a 2D multivector, with one complex number for the vector part, and a complex number for the scalar and pseudoscalar parts.  That technique has been detailed on this blog previously, and also in a Mathematica module Cl20.m.

Trying to implement a couple of complex number operations in COBOL got absurd really fast.  Here’s an example.  First step was to create some complex number types.  I did that with a copybook (include file), like so:

This can be included multiple times, each time with a different name, like so:

The way that I structured all my helper functions, was with one set of global variables for input (at least one), and if appropriate, one output global variable.  Here’s an example:

So, if I want to compute and display a value, I have a whole pile of stupid MOVEs to do in and out of the appropriate global variables for each of the helper routines in question:

I wrote enough of this little complex number library that I could do conjugate, real, imaginary, multiply, inverse, and divide operations.  I can run that little program with the following JCL

//COMPLEX JOB
//A EXEC PGM=COMPLEX
//SYSOUT   DD SYSOUT=*
//STEPLIB  DD DSN=PJOOT.SAMPLE.COMPLEX,
//  DISP=SHR

and get this SYSOUT:

STEP A SYSOUT:
A                    =  .10000000000000000E 01 + ( .20000000000000000E 01) I
B                    =  .30000000000000000E 01 + ( .40000000000000000E 01) I
CONJ(A)              =  .10000000000000000E 01 + (-.20000000000000000E 01) I
RE(A)                =  .10000000000000000E 01
IM(A)                =  .20000000000000000E 01
A * B                = -.50000000000000000E 01 + ( .10000000000000000E 02) I
1/A                  =  .20000000000000000E 00 + (-.40000000000000000E 00) I
A/B                  =  .44000000000000000E 00 + ( .80000000000000000E-01) I

If you would like your eyes burned further, you can access the full program on github here. It takes almost 200 lines of code to do almost nothing.

A silly geometry problem: length of side of square in circular quadrant

September 27, 2023 math and physics play , ,

[Click here for a PDF version of this post]

Problem from:

My solution (before numerical reduction), using basic trig and complex numbers, is illustrated in fig. 1.

fig. 1. With complex numbers.

We have
\begin{equation}\label{eqn:squareInCircle:20}
\begin{aligned}
s &= x \cos\theta \\
y &= x \sin\theta \\
p &= y + x e^{i\theta} \\
q &= i s + x e^{i\theta} \\
\Abs{q} &= y + 5 \\
\Abs{p – q} &= 2.
\end{aligned}
\end{equation}
This can be reduced to
\begin{equation}\label{eqn:squareInCircle:40}
\begin{aligned}
\Abs{ x e^{i\theta} – 5 } &= 2 \\
x \Abs{ i \cos\theta + e^{i\theta} } &= x \sin\theta + 5.
\end{aligned}
\end{equation}

My wife figured out how to do it with just Pythagoras, as illustrated in fig. 2.

fig. 2.  With Pythagoras.

fig. 2. With Pythagoras.

\begin{equation}\label{eqn:squareInCircle:60}
\begin{aligned}
\lr{ 5 – s }^2 + y^2 &= 4 \\
\lr{ s + y }^2 + s^2 &= \lr{ y + 5 }^2 \\
x^2 &= s^2 + y^2.
\end{aligned}
\end{equation}

Either way, the numerical solution is 4.12. The geometry looks like fig. 3.

fig. 3. Lengths to scale.

A mathematica notebook to compute the numerical part of the problem (either way) and plot the figure to scale can be found in my mathematica github repo.

A complex-pair representation of GA(2,0).

June 15, 2023 math and physics play , , , ,

[Click here for a PDF version of this post]

Motivation.

Suppose that we want to represent GA(2,0) (Euclidean) multivectors as a pair of complex numbers, with a structure like
\begin{equation}\label{eqn:bicomplexGA20:20}
M = (m_1, m_2),
\end{equation}
where
\begin{equation}\label{eqn:bicomplexGA20:40}
\begin{aligned}
\gpgrade{M}{0,2} &\sim m_1 \\
\gpgrade{M}{1} &\sim m_2.
\end{aligned}
\end{equation}
Specifically
\begin{equation}\label{eqn:bicomplexGA20:60}
\begin{aligned}
\gpgrade{M}{0} &= \textrm{Re}(m_1) \\
\gpgrade{M}{1} \cdot \Be_1 &= \textrm{Re}(m_2) \\
\gpgrade{M}{1} \cdot \Be_2 &= \textrm{Im}(m_2) \\
\gpgrade{M}{2} i^{-1} &= \textrm{Im}(m_1),
\end{aligned}
\end{equation}
where \( i \sim \Be_1 \Be_2 \).

Multivector product representation.

Let’s figure out how we can represent the various GA products, starting with the geometric product. Let
\begin{equation}\label{eqn:bicomplexGA20:80}
\begin{aligned}
M &= \gpgrade{M}{0,2} + \gpgrade{M}{1} = (m_1, m_2) = (m_{11} + m_{12} i, m_{21} + m_{22} i) \\
N &= \gpgrade{N}{0,2} + \gpgrade{N}{1} = (n_1, n_2) = (n_{11} + n_{12} i, n_{21} + n_{22} i),
\end{aligned}
\end{equation}
so
\begin{equation}\label{eqn:bicomplexGA20:200}
\begin{aligned}
M N
&= \gpgrade{M}{0,2} \gpgrade{N}{0,2} + \gpgrade{M}{1} \gpgrade{N}{1} \\
&\quad+ \gpgrade{M}{1} \gpgrade{N}{0,2} + \gpgrade{M}{0,2} \gpgrade{N}{1}
\end{aligned}
\end{equation}

The first two terms have only even grades, and the second two terms are vectors. The complete representation of the even grade components of this multivector product is
\begin{equation}\label{eqn:bicomplexGA20:240}
\gpgrade{M N}{0,2} \sim \lr{ m_1 n_1 + \textrm{Re}(m_2 n_2^\conj) – i \textrm{Im}(m_2 n_2^\conj), 0 },
\end{equation}
or
\begin{equation}\label{eqn:bicomplexGA20:260}
\begin{aligned}
\gpgrade{M N}{0} &= \textrm{Re}\lr{ m_1 n_1 + m_2 n_2^\conj } \\
\gpgrade{M N}{2} i^{-1} &= \textrm{Im}\lr{ m_1 n_1 – m_2 n_2^\conj }.
\end{aligned}
\end{equation}

For the vector components we have
\begin{equation}\label{eqn:bicomplexGA20:280}
\begin{aligned}
\gpgrade{M N}{1}
&=
\gpgrade{M}{1} \gpgrade{N}{0} + \gpgrade{M}{0} \gpgrade{N}{1}
+
\gpgrade{M}{1} \gpgrade{N}{2} + \gpgrade{M}{2} \gpgrade{N}{1} \\
&= \gpgrade{M}{1} n_{11} + m_{11} \gpgrade{N}{1} + \gpgrade{M}{1} i n_{12} + i m_{12} \gpgrade{N}{1}.
\end{aligned}
\end{equation}
For these,
\begin{equation}\label{eqn:bicomplexGA20:300}
\begin{aligned}
\gpgrade{M}{1} i
&= \lr{ m_{21} \Be_1 + m_{22} \Be_2 } \Be_{12}
&= – m_{22} \Be_1 + m_{21} \Be_2,
\end{aligned}
\end{equation}
and
\begin{equation}\label{eqn:bicomplexGA20:320}
\begin{aligned}
i \gpgrade{N}{1}
&= \Be_{12} \lr{ n_{21} \Be_1 + n_{22} \Be_2 }
&=
n_{22} \Be_1 – n_{21} \Be_2.
\end{aligned}
\end{equation}
Comparing to
\begin{equation}\label{eqn:bicomplexGA20:340}
i (a + i b)
= -b + i a,
\end{equation}
we see that
\begin{equation}\label{eqn:bicomplexGA20:360}
\gpgrade{M N}{1}
\sim
\lr{ 0, n_{11} m_2 + m_{11} n_2 + n_{12} i m_2 – m_{12} i n_2 }.
\end{equation}
If we want the vector coordinates, those are
\begin{equation}\label{eqn:bicomplexGA20:380}
\begin{aligned}
\gpgrade{M N}{1} \cdot \Be_1 &= \textrm{Re} \lr{ n_{11} m_2 + m_{11} n_2 + n_{12} i m_2 – m_{12} i n_2 } \\
\gpgrade{M N}{1} \cdot \Be_2 &= \textrm{Im} \lr{ n_{11} m_2 + m_{11} n_2 + n_{12} i m_2 – m_{12} i n_2 }.
\end{aligned}
\end{equation}

Summary.

\begin{equation}\label{eqn:bicomplexGA20:n}
M N \sim
\lr{ m_1 n_1 + \textrm{Re}(m_2 n_2^\conj) – i \textrm{Im}(m_2 n_2^\conj), n_{11} m_2 + m_{11} n_2 + n_{12} i m_2 – m_{12} i n_2 }.
\end{equation}

A sample Mathematica implementation is available, as well as an example notebook (that also doubles as a test case.)

Clarification.

I skipped a step above, showing the correspondances to the dot and wedge product.

Let \(z = a + bi\), and \(w = c + di\). Then:
\begin{equation}\label{eqn:bicomplexGA20:420}
\begin{aligned}
z w^\conj
&=
\lr{ a + b i } \lr{ c – d i } \\
&= a c + b d -i \lr{ a d – b c }.
\end{aligned}
\end{equation}
Compare that to the geometric product of two vectors \( \Bx = a \Be_1 + b \Be_2 \), and \( \By = c \Be_1 + d \Be_2 \), where we have
\begin{equation}\label{eqn:bicomplexGA20:440}
\begin{aligned}
\Bx \By &= \Bx \cdot \By + \Bx \wedge \By \\
&= \lr{ a \Be_1 + b \Be_2 } \lr{ c \Be_1 + d \Be_2 } \\
&= a c + b d + \Be_1 \Be_2 \lr{ a d – b c }.
\end{aligned}
\end{equation}
So we have
\begin{equation}\label{eqn:bicomplexGA20:460}
\begin{aligned}
a b + cd &= \Bx \cdot \By = \textrm{Re} \lr{ z w^\conj } \\
a d – b c &= \lr{ \Bx \wedge \By } \Be_{12}^{-1} = – \textrm{Im} \lr{ z w^\conj }.
\end{aligned}
\end{equation}
We see that \( \lr{z w^\conj}^\conj = z^\conj w \) can be used as a representation of the geometric product of two vectors (setting \( i = \Be_1 \Be_2 \) as usual.)

Another simplification.

We have sums of the form
\begin{equation}\label{eqn:bicomplexGA20:480}
\textrm{Re}(z) w \pm \textrm{Im}(z) i w
\end{equation}
above. Let’s see if those can be simplified. For the positive case we have
\begin{equation}\label{eqn:bicomplexGA20:500}
\begin{aligned}
\textrm{Re}(z) w + \textrm{Im}(z) i w
&=
\inv{2} \lr{ z + z^\conj } w + \inv{2} \lr{ z – z^\conj } w \\
&=
z w,
\end{aligned}
\end{equation}
and for the negative case, we have
\begin{equation}\label{eqn:bicomplexGA20:520}
\begin{aligned}
\textrm{Re}(z) w – \textrm{Im}(z) i w
&=
\inv{2} \lr{ z + z^\conj } w – \inv{2} \lr{ z – z^\conj } w \\
&=
z^\conj w.
\end{aligned}
\end{equation}
This, with the vector-vector product simplification above, means that we can represent the full multivector product in this representation as just
\begin{equation}\label{eqn:bicomplexGA20:540}
M N \sim
\lr{ m_1 n_1 + m_2^\conj n_2, m_2 n_1 + m_1^\conj n_2 }.
\end{equation}

Inscribed Triangle in circle problem

December 25, 2022 math and physics play , , , , , ,

[Click here for a PDF version of this post]

In the LinkedIn Pre-University Geometric Algebra group, James presents a problem from the MindYourDecisions youtube channel Impossible Viral Problem, as a candidate for solution using geometric algebra.

I tried this out and found a couple ways to solve it. One of those I’ll detail here. I have to admit that part of the reason that I wanted to solve this is that the figure in the beginning of the video really bugged me. The triangle that was inscribed in the circle didn’t have any of the length properties from the problem. I could do much better with a sloppy freehand sketch, but to do a good figure, you have to actually solve for the vertexes of the triangle (once you do that, the area is easy to figure out.)

Formulating the problem.

Having solved the problem, the geometry of the problem is illustrated in fig. 1.

fig. 1. Inscribed triangle in circle.

fig. 1. Inscribed triangle in circle.

I set up the problem so that the \( A,C \) triangle vertices were symmetric with respect to the x-axis, and the \(B \) vertex located elsewhere. I can describe those algebraically as
\begin{equation}\label{eqn:inscribedTriangleProblem:20}
\begin{aligned}
\BA &= r \Be_1 e^{i\theta} \\
\BC &= r \Be_1 e^{-i\theta} \\
\BB &= r \Be_1 e^{i\phi},
\end{aligned}
\end{equation}
where the radius \( r \) and two angles \( \theta, \phi \) are to be determined, and \( i = \Be_1 \Be_1\) the pseudoscalar for the \(x-y\) plane.
The vector pointing to the midpoint of the upper triangular face is given by the average of the \( \BA, \BB \) vectors, which can be seen from
\begin{equation}\label{eqn:inscribedTriangleProblem:40}
\BA + \frac{\BB – \BA}{2} = \frac{\BA + \BB}{2},
\end{equation}
and similarly, the midpoint of the lower face is found at
\begin{equation}\label{eqn:inscribedTriangleProblem:60}
\BC + \frac{\BB – \BC}{2} = \frac{\BB + \BC}{2},
\end{equation}
The problem tells us that the respective lengths of those vectors from the origin are \( r-2, r – 3\) respectively, so
\begin{equation}\label{eqn:inscribedTriangleProblem:80}
\begin{aligned}
r – 2 &= \inv{2} \Abs{ \BA + \BB } \\
r – 3 &= \inv{2} \Abs{ \BB + \BC },
\end{aligned}
\end{equation}
or
\begin{equation}\label{eqn:inscribedTriangleProblem:100}
\begin{aligned}
(r – 2)^2 &= \frac{r^2}{4} \lr{ \Be_1 e^{i\theta} + \Be_1 e^{i\phi} }^2 \\
(r – 3)^2 &= \frac{r^2}{4} \lr{ \Be_1 e^{i\phi} + \Be_1 e^{-i\theta} }^2 \\
\end{aligned}
\end{equation}
Finally, since the midpoint of the right edge is found at \( (r-1)\Be_1 \), it is clear that
\begin{equation}\label{eqn:inscribedTriangleProblem:120}
\frac{r-1}{r} = \cos\theta,
\end{equation}
or
\begin{equation}\label{eqn:inscribedTriangleProblem:140}
r = \inv{1 – \cos\theta}.
\end{equation}
This leaves us with three equations and three unknowns. Unfortunately, these are rather non-linear equations. In the video, a direct method of solving equivalent equations was demonstrated, but I picked the lazy route, and used Mathematica’s NSolve routine, solving for \( r,\theta, \phi\) numerically. Since NSolve has intrinsic complex number support, I made the following substitutions:
\begin{equation}\label{eqn:inscribedTriangleProblem:160}
\begin{aligned}
z &= e^{i\theta} \\
w &= e^{i\phi},
\end{aligned}
\end{equation}
and then plugged those into our relations above, after expanding the squares, to find
\begin{equation}\label{eqn:inscribedTriangleProblem:180}
\begin{aligned}
\lr{ \Be_1 e^{i\theta} + \Be_1 e^{i\phi} }^2
&=
2 + \Be_1 e^{i\theta} \Be_1 e^{i\phi} + \Be_1 e^{i\phi} \Be_1 e^{i\theta} \\
&=
2 + e^{-i\theta} \Be_1^2 e^{i\phi} + e^{-i\phi} \Be_1^2 e^{i\theta} \\
&=
2 + e^{-i\theta} \Be_1^2 e^{i\phi} + e^{-i\phi} \Be_1^2 e^{i\theta} \\
&=
2 + \frac{w}{z} + \frac{z}{w},
\end{aligned}
\end{equation}
and
\begin{equation}\label{eqn:inscribedTriangleProblem:200}
\begin{aligned}
\lr{ \Be_1 e^{i\phi} + \Be_1 e^{-i\theta} }^2
&=
2 + \Be_1 e^{i\phi} \Be_1 e^{-i\theta} + \Be_1 e^{-i\theta} \Be_1 e^{i\phi} \\
&=
2 + e^{-i\phi} e^{-i\theta} + e^{ i\theta} e^{i\phi} \\
&=
2 + w z + \inv{w z}.
\end{aligned}
\end{equation}
This gives us
\begin{equation}\label{eqn:inscribedTriangleProblem:220}
\begin{aligned}
4 \lr{ \frac{r – 2 }{r} }^2 &= 2 + \frac{w}{z} + \frac{z}{w} \\
4 \lr{ \frac{r – 3 }{r} }^2 &= 2 + w z + \inv{w z},
\end{aligned}
\end{equation}
where
\begin{equation}\label{eqn:inscribedTriangleProblem:240}
r = \inv{1 – \inv{2}\lr{ z + \inv{z}}}.
\end{equation}

The NSolve gave me some garbage solutions (like \(\theta = 0 \)) that must have been valid numerically, but did not encode the geometry of the problem, so I added a few additional constraints to the problem, namely
\begin{equation}\label{eqn:inscribedTriangleProblem:260}
\begin{aligned}
z \bar{z} &= 1 \\
w \bar{w} &= 1 \\
\inv{2} \lr{ z + \inv{z} } &\ne 1 \\
1/(1 – (1/2) \textrm{Re}(z + 1/z)) &> 3.
\end{aligned}
\end{equation}
This provided exactly two solutions, but when plotted, they turn out to just be mirror images of each other. After back substitution, the solution illustrated above was given by
\begin{equation}\label{eqn:inscribedTriangleProblem:280}
\begin{aligned}
r &= 3.87939 \\
\theta &= 42.078 \\
\phi &= 164.125,
\end{aligned}
\end{equation}
where these angles are in degrees, not radians.

The triangular area.

There are probably lots of formulas for the area of a triangle (that I have forgotten), but we can compute it easily by doubling the triangle, forming a parallelogram, to find
\begin{equation}\label{eqn:inscribedTriangleProblem:300}
\textrm{Area} = \inv{2} \Abs{ \lr{ \BA – \BC } \wedge {\BC – \BB } },
\end{equation}
or
\begin{equation}\label{eqn:inscribedTriangleProblem:320}
\begin{aligned}
\textrm{Area}^2
&= \frac{-1}{4} \lr{ \lr{ \BA – \BC } \wedge \lr{\BC – \BB } }^2 \\
&= \frac{-1}{4} \lr{ \BA \wedge \BC – \BA \wedge \BB + \BC \wedge \BB }^2 \\
&= \frac{-r^4}{4} \lr{\gpgradetwo{ \Be_1 e^{i\theta} \Be_1 e^{-i\theta} – \Be_1 e^{i\theta} \Be_1 e^{i\phi} + \Be_1 e^{-i\theta} \Be_1 e^{i\phi} }}^2 \\
&= \frac{-r^4}{4} \lr{\gpgradetwo{ e^{-2 i \theta} – e^{i \phi -i\theta} + e^{i\theta + i \phi} }}^2,
\end{aligned}
\end{equation}
so
\begin{equation}\label{eqn:inscribedTriangleProblem:340}
\textrm{Area} = \frac{r^2}{2} \Abs{ -\sin( 2 \theta ) – \sin(\phi- \theta) + \sin(\theta + \phi)}.
\end{equation}
Plugging in \( r, \theta, \phi \), we find
\begin{equation}\label{eqn:inscribedTriangleProblem:360}
\textrm{Area} = 17.1866.
\end{equation}
After computing this value, I then finally watched the original video to compare my answer, and was initially disturbed to find that this wasn’t even one of the possible values. However, that was because the problem itself, as originally stated, didn’t include the correct answer, and my worry that I’d made a mistake was unfounded, as the value I computed matched what was computed in the video (it also looks “about right” visually.)