# Math Functions # Math Functions Support

The Fractal Science Kit fractal generator Math functions are a collection of basic math related functions.

void Math.LogN(z, N) = Log(z)/Log(N)

Math.LogN returns the log base N of z.

void Math.ApplyQuadraticFormula(A, B, C, byref root0, byref root1)

Math.ApplyQuadraticFormula finds the 2 solutions to the equation: A*x^2+B*x+C=0 and returns them in root0 and root1. If a single solution is found, it is returned in both root0 and root1. A, B, C, root0, and root1 are complex.

void Math.NormalizeWeights(weights[], count)

Math.NormalizeWeights normalizes the count values in weights[]. On return, the values will all be between 0 and 1, and the sum of all values will equal 1.

'
' Scale the weights in weights[] such that
'
' power < 0 decreases spread
' power = 0 has no effect
' power > 0 increases spread
'

Math.SpreadWeights modifies the count values in weights[] as described in the comments above. It is assumed that the values in weights[] are normalized when the function is called. On return, the values are modified as described and renormalized.

void Math.GenerateIndexLookupTable(weights[], count, Complex indexLUT[])
Complex Math.GenerateIndex(Complex indexLUT[])

Math.GenerateIndexLookupTable populates the look-up table indexLUT[] for use by Math.GenerateIndex. The array weights[] is assumed to contain count normalized values. Typically, the look-up table indexLUT[] should be dimensioned 1000 or more, based on the given weights; i.e., the dimension should be greater than the reciprocal of the smallest weight. Math.GenerateIndex generates a random index based on look-up table indexLUT[] assumed to have been populated by Math.GenerateIndexLookupTable.

Math.NewtonMethod(z, f0, f1, z0)
Math.NewtonMethod2(z, f0, z0)

The Math.NewtonMethod and Math.NewtonMethod2 macros are #Define Statements that support finding roots of single-valued functions. They are defined in the built-in macros.

Math.NewtonMethod applies Newton's method to find a root of the equation given by f0. The 1st argument z is the variable used in the equations f0 and f1. f1 is the 1st derivative of f0. z0 is the initial guess required by Newton's method and should be a complex constant. The resulting root, is assigned to the variable named in the 1st argument. Remember that all macro arguments must be quoted strings as in the following example.

Example:

#include Math.NewtonMethod("z", "Cos(z)-2*z", "-Sin(z)-2", "0")

This statement uses Newton's method to compute the value of z such that f(z)=0 for the following equation:

f(z) = Cos(z)-2*z

The 1st derivative of f(z) is:

f'(z) = -Sin(z)-2

Both f0 and f1 are given in terms of the variable z which is named in the 1st argument ("z"). The initial guess is 0 and is given by the last argument ("0"). This statement results in setting z to the value such that f(z)=0. The value of the root is placed in the variable given by the argument z (the variable z in this example). The following example shows how this statement could be used by your program to find the critical point of a Mandelbrot fractal.

Example:

global:

if (~IsJulia) {
'
' The following calculates the critical point
' using Newton's method for solving an equation.
'
#include Math.NewtonMethod("z", "Cos(z)-2*z", "-Sin(z)-2", "0")
'
' The result is placed in the variable named in
' the first argument to the function ("z").
' Save this in z0 so we can initialize z below.
'
z0 = z
}

initialize:

if (~IsJulia) {
z = z0 ' critical point
}

The 2nd macro, Math.NewtonMethod2, is identical to Math.NewtonMethod, except that it does not require the f1 argument and approximates the value of the derivative instead. While this is less effective than the previous method, it is acceptable in most cases and eliminates the need to calculate the function's derivative.

Example:

#include Math.NewtonMethod2("z", "K*(K-1)*z^(K-2)-Log(K)^2*K^z", "1")
z0 = z

Given the complexity of f0 above, it would be tedious to derive the derivative so we can use Math.NewtonMethod2.

Complex Math.ArithmeticMean(z1,z2)
Complex Math.GeometricMean(z1,z2)
Complex Math.HarmonicMean(z1,z2)
Complex Math.ContraHarmonicMean(z1,z2)
Complex Math.LogarithmicMean(z1,z2)
Complex Math.Power2Mean(z1,z2)
Complex Math.Power3Mean(z1,z2)

These functions return the named mean value given 2 arguments.

Complex Math.ChebyshevDistance(p, q)
Complex Math.ManhattanDistance(p, q)
Complex Math.EuclidianDistance(p, q, rooted)
Complex Math.MinkovskyDistance(p, q, power, rooted)

These functions return the named distance metric between the points p and q.

rooted is a Boolean value that you can use to omit the the root function applied to the sum of the deltas.

For the Minkovsky distance function, power is used to control the power applied to the x and y coordinate deltas and should be greater than 0. If power is less than or equal to 0, power=1 is used instead. If power=1, the function is equivalent to the Manhattan distance function. If power=2, the function is equivalent to the Euclidian distance function.

'
' Note that sa=Sin(a) and ca=Cos(a) below.
'
Complex Math.Cos2(ca)     = Cos(2*a)
Complex Math.Cos3(ca)     = Cos(3*a)
Complex Math.Cos4(ca)     = Cos(4*a)
Complex Math.Sin2(sa, ca) = Sin(2*a)
Complex Math.Sin3(sa)     = Sin(3*a)
Complex Math.Sin4(sa, ca) = Sin(4*a)

The functions compute the Sin and Cos of multiples of an angle given the value of the Sin and/or Cos of the base angle. These can be used to avoid additional Sin/Cos function calls if Sin and Cos of the base angle are known.

'
' Note that sa=Sinh(a) and ca=Cosh(a) below.
'
Complex Math.Cosh2(ca)     = Cosh(2*a)
Complex Math.Cosh3(ca)     = Cosh(3*a)
Complex Math.Cosh4(ca)     = Cosh(4*a)
Complex Math.Sinh2(sa, ca) = Sinh(2*a)
Complex Math.Sinh3(sa)     = Sinh(3*a)
Complex Math.Sinh4(sa, ca) = Sinh(4*a)

The functions compute the Sinh and Cosh of multiples of an angle given the value of the Sinh and/or Cosh of the base angle. These can be used to avoid additional Sinh/Cosh function calls if Sinh and Cosh of the base angle are known.

Complex Math.UpdateMinArray(r, rmin[])
Complex Math.UpdateMaxArray(r, rmax[])

Math.UpdateMinArray checks r against the values in rmin[] and inserts r into rmin[] if it is less than any of the existing items. r and rmin[] are floats and rmin[] should be ordered from low to high. r is inserted at the smallest index p in rmin[] such that r < rmin[i] for all i >= p, and the items in rmin[] at index p and above are shifted to make room, discarding the last item. The index p where r is inserted is returned as the function value. If r is >= all values in rmin[], the function returns -1.

Math.UpdateMaxArray checks r against the values in rmax[] and inserts r into rmax[] if it is greater than any of the existing items. r and rmax[] are floats and rmax[] should be ordered from high to low. r is inserted at the smallest index p in rmax[] such that r > rmax[i] for all i >= p, and the items in rmax[] at index p and above are shifted to make room, discarding the last item. The index p where r is inserted is returned as the function value. If r is <= all values in rmax[], the function returns -1.

Math.BlendValues(blendType, blendArgR, blendAbs, values[], count)

Math.BlendValues returns the blended value given by blendType of the count values in the array values[]. The different blend types are defined in an enum called BlendTypes as shown below:

#define BlendTypes

enum BlendTypes {
Minimum,            "Minimum"
Sum,                "Sum"
Product,            "Product"
PowerMeanNeg2,      "Power Mean: -2"
PowerMeanNeg1,      "Power Mean: -1 (Harmonic Mean)"
PowerMean0,         "Power Mean: 0 (Geometric Mean)"
PowerMean1,         "Power Mean: 1 (Arithmetic Mean)"
PowerMean2,         "Power Mean: 2 (Quadratic Mean)"
LehmerMeanNeg2,     "Lehmer Mean: -2"
LehmerMeanNeg1,     "Lehmer Mean: -1"
LehmerMean0,        "Lehmer Mean: 0 (Harmonic Mean)"
LehmerMean1,        "Lehmer Mean: 1 (Arithmetic Mean)"
LehmerMean2,        "Lehmer Mean: 2 (ContraHarmonic Mean)"
GeneralizedMean1,   "Generalized Mean: f(x)=(x+R)/(x-R)"
GeneralizedMean2,   "Generalized Mean: f(x)=(R-x)/(x+R)"
GeneralizedMean3,   "Generalized Mean: f(x)=1/(R+x)+1/(R-x)"
GeneralizedMean4,   "Generalized Mean: f(x)= x/(R+x)-x/(R-x)"
GeneralizedMean5,   "Generalized Mean: f(x)=Sin(R*x)"
GeneralizedMean6,   "Generalized Mean: f(x)=Cos(R*x)"
GeneralizedMean7,   "Generalized Mean: f(x)=Tan(R*x)"
GeneralizedMean8,   "Generalized Mean: f(x)=Cot(R*x)"
GeneralizedMean9,   "Generalized Mean: f(x)=Sec(R*x)"
GeneralizedMean10,  "Generalized Mean: f(x)=Csc(R*x)"
GeneralizedMean11,  "Generalized Mean: f(x)=Sinh(x)"
GeneralizedMean12,  "Generalized Mean: f(x)=Csch(x)"
GeneralizedMean13,  "Generalized Mean: f(x)=Log(x)"
GeneralizedMean14,  "Generalized Mean: f(x)=Exp(x)"
Variance,           "Variance"
}
#end

You can #include BlendTypes in the properties section of your instructions to access this enum.

The remaining arguments are floats. blendArgR is the value R in the descriptions above and is only used in some of the blend types. blendAbs is a Boolean value used to blend the absolute value of the values in the array rather than the raw values.

Math.Wave(r, type, amplitude, period, shift)

Math.Wave returns the value at r of the wave given by type. The different wave types are defined in an enum called WaveTypes as shown below:

#define WaveTypes

enum WaveTypes {
Sine,      "Sine"
Triangle,  "Triangle"
Sawtooth,  "Sawtooth"
}
#end

You can #include WaveTypes in the properties section of your instructions to access this enum.

The remaining arguments are floats. Amplitude can be either positive or negative but must not equal 0 and is the amplitude of the wave. Period is the period of the wave and must be greater than 0. Shift, given as a percent of period, shifts the curve, left or right, and is a value between 0 and 1, inclusive.

Math.GCD(a, b)
Math.SymmetricPower(r, power)
Math.PowerSmooth(r, power)

Math.GCD returns the greatest common divisor of a and b. Both a and b should be positive integers.

Math.SymmetricPower returns returns Sign(r)*Abs(r)^power.

Math.PowerSmooth returns the smoothed value of r based on power. r must be between 0 and 1 inclusive. power should be greater than or equal to 1. power=1 does not change r. power greater than 1 applies smoothing to r increasing with power.

void Math.NextPQ(byref p, byref q, N)

Math.NextPQ is an implementation of the nextpq method given in Box 28 on page 307 of in the book by David Mumford, Caroline Series, and David Wright. Given a fraction p/q in a Farey sequence of order N, Math.NextPQ returns the next fraction p/q in the sequence. The fraction is returned in the variables p and q.