Relevant code:
This first one is where it starts that one only wraps his inner routine:
static REALobject SinhCM(REALobject instance)
{
ClassData(ComplexMatrixClass, instance, ComplexMatrixData, data);
if (data->nr < 1 || data->nc < 1 || data->nr != data->nc)
{
ThrowRowColumnMismatchException();
REALLockObject(instance);
return instance;
}
REALobject z = REALnewInstanceOfClass(&ComplexMatrixClass);
ClassData(ComplexMatrixClass, z, ComplexMatrixData, zData);
zData->nr = data->nr;
zData->nc = data->nc;
zData->array = (Complex**)malloc(zData->nr * sizeof(Complex*));
for (int32_t i = 0; i < zData->nr; i++)
zData->array[i] = (Complex*)malloc(zData->nc * sizeof(Complex));
mySinhCM(zData->array, data->array, zData->nr);
return z;
}/* SinhCM */
Then it goes to his inner routine:
void mySinhCM(Complex **z, Complex **x, int n)
{
Complex **temp;
long i, j;
if(n<=0)
return;
if(n==1)
{
z[0][0].Re = sinh(x[0][0].Re)*cos(x[0][0].Im);
z[0][0].Im = cosh(x[0][0].Re)*sin(x[0][0].Im);
return;
}
temp = (Complex **)malloc(n*sizeof(Complex *));
for (i=0;i<n;i++)
temp[i] = (Complex *)malloc(n*sizeof(Complex));
EquateCM_CM(temp, x, n); // temp = x
NegateCM(temp, n); // temp = -x
myExpCM(z, temp, n); // z = exp(-x)
EquateCM_CM(temp, z, n); // temp = exp(-x)
myExpCM(z, x, n); // z = exp(x)
SubCM_CM(z, z, temp, n); // z = exp(x) - exp(-x)
DivCM_D(z, 2, n); // z = sinh(x)
// we cannot have any extremely small but non-zero elements
for(i=0;i<n;++i)
{
for(j=0;j<n;++j)
{
if(dabs(z[i][j].Re)<zeroDouble)
z[i][j].Re = 0;
if(dabs(z[i][j].Im)<zeroDouble)
z[i][j].Im = 0;
}
}
for(i=0;i<n;i++)
free(temp[i]);
free(temp);
}/* mySinhCM */
And as you can see then his inner routine calls several others…
static inline void EquateCM_CM(Complex **z, Complex **x, int n)
{
long i, j;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
z[i][j] = x[i][j];
}/* EquateCM_CM */
static inline void NegateCM(Complex **z, int n)
{
long i, j;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
NegateCC(z[i][j]);
}/* NegateCM */
oid myExpCM(Complex **z, Complex **x, int n)
{
long i, j, k;
Complex **temp, **currentTerm, **zCurrent;
double temp1;
double maxEl;
int m;
Complex **xt;
if(n<=0)
return;
if(n==1)
{
temp1 = exp(x[0][0].Re);
z[0][0].Re = temp1*cos(x[0][0].Im);
z[0][0].Im = temp1*sin(x[0][0].Im);
return;
}
// find maximum element of x in absolute value
maxEl = 0;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(AbsC(x[i][j])>maxEl)
maxEl = AbsC(x[i][j]);
if(maxEl==0)
{
// z = unit matrix
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(i==j)
{
z[i][j].Re = 1.;
z[i][j].Im = 0;
}
else
{
z[i][j].Re = 0;
z[i][j].Im = 0;
}
return;
}
xt = (Complex **)malloc(n*sizeof(Complex *));
for (i=0;i<n;i++)
xt[i] = (Complex *)malloc(n*sizeof(Complex));
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
xt[i][j].Re = x[i][j].Re;
xt[i][j].Im = x[i][j].Im;
}
m = 1;
if(maxEl<(double)0x7FFFFFFF)
{
m = (int)maxEl;
m++;
if(m>1)
{
// divide matrix xt by m
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
xt[i][j].Re = xt[i][j].Re/m;
xt[i][j].Im = xt[i][j].Im/m;
}
}
}
temp = (Complex **)malloc(n*sizeof(Complex *));
for (i=0;i<n;i++)
temp[i] = (Complex *)malloc(n*sizeof(Complex));
currentTerm = (Complex **)malloc(n*sizeof(Complex *));
for (i=0;i<n;i++)
currentTerm[i] = (Complex *)malloc(n*sizeof(Complex));
zCurrent = (Complex **)malloc(n*sizeof(Complex *));
for (i=0;i<n;i++)
zCurrent[i] = (Complex *)malloc(n*sizeof(Complex));
// make z, currentTerm, and zCurrent Unit matrices
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(i==j)
{
z[i][j].Re = currentTerm[i][j].Re = zCurrent[i][j].Re = 1;
z[i][j].Im = currentTerm[i][j].Im = zCurrent[i][j].Im = 0;
}
else
{
z[i][j].Re = currentTerm[i][j].Re = zCurrent[i][j].Re = 0;
z[i][j].Im = currentTerm[i][j].Im = zCurrent[i][j].Im = 0;
}
for(k=1; ;k++)
{
MulCM_CM(temp, xt, currentTerm, n);
EquateCM_CM(currentTerm, temp, n);
DivCM_D(currentTerm, k, n);
AddCM_CM(z, z, currentTerm, n);
if(isEqualCM_CM(z, zCurrent, n))
break;
EquateCM_CM(zCurrent, z, n);
}
if(m>1)
{
myPowerCM(z, zCurrent, m, n);
}
// we cannot have any extremely small but non-zero elements
for(i=0;i<n;++i)
{
for(j=0;j<n;++j)
{
if(dabs(z[i][j].Re)<zeroDouble)
z[i][j].Re = 0;
if(dabs(z[i][j].Im)<zeroDouble)
z[i][j].Im = 0;
}
}
for(i=0;i<n;i++)
{
free(xt[i]);
free(temp[i]);
free(currentTerm[i]);
free(zCurrent[i]);
}
free(xt);
free(temp);
free(currentTerm);
free(zCurrent);
}/* myExpCM */
static inline void SubCM_CM(Complex **z, Complex **x, Complex **y, int n)
{
long i, j;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
SubCC(z[i][j], x[i][j], y[i][j]);
}/* SubCM_CM */
static inline void SubCC(Complex& z, const Complex& x, const Complex& y)
{
z.Re = x.Re - y.Re;
z.Im = x.Im - y.Im;
}/* SubCC */
static inline void DivCM_D(Complex **z, int k, int n)
{
long i, j;
if(k==0)
return;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
DivCC_D(z[i][j], (double)k);
}/* DivCM_D */
static inline void DivCC_D(Complex& z, double x)
{
z.Re = z.Re/x;
z.Im = z.Im/x;
}/* DivCC_D */
A bit of a total spaghetti as you can see.
I do not know at what stage it crashes. (it would be easier to realize that if knowing how to generate the crash without the loop in Xojo)