# General Functions # General Functions Support

This section describes a set of general functions available to your Fractal Science Kit fractal programs.

Complex(re, im) -> return z where z.r = re  : z.i = im
Polar(rad, ang) -> return z where z.r = rad : z.a = ang

The functions Complex and Polar return a complex value given 2 floats. Polar is, in fact, identical to Complex but can be used to clarify your code when you are initializing a complex variable to a polar representation. Functions are also provided to convert between complex and polar representations.

Example:

z = Complex(0, 1)
p = ComplexToPolar(z)
...
p = Polar(1, Math.PI/2)
z = PolarToComplex(p)

In this example, z and p represent the complex value 0+1i. In the 1st case we set z directly and convert z to polar form (p) using the ComplexToPolar function. In the 2nd case, we set p directly and convert p to complex form (z) using the PolarToComplex function. See Variables for details.

Object.Size(<ObjectTypeName>)

Object.Size returns the size of objects of the given type. <ObjectTypeName> should be the name of an existing object type. The returned value is the number of fields that are defined for the given type.

Example:

size = Object.Size(Circle)

This sets size to 3, the number of fields defined for the type Circle.

IIf(<Condition>, <Value-If-True>, <Value-If-False>)

The IIf function evaluates the conditional expression and evaluates/returns 1 of the 2 expressions based on the result. IIf is handled differently than other functions in that only 1 of the expressions <Value-If-True> or <Value-If-False> is evaluated, depending on the conditional expression. Contrast this with the way all other functions are invoked where we evaluate all the function's arguments before calling the function. IIf can return an object or a complex number but <Value-If-True>, <Value-If-False>, and the variable to which the function result is assigned, must all be the same type. IIf cannot return an array.

Example:

r = IIf(x = 0, 1, Sin(x)/x)

This statement sets r to different values based on the value of x.

Ident(z) = z

Ident simply returns its argument. This function is frequently included as one of the functions that define a function proxy option to provide a way to return an unmodified value.

Re(z) = z.r
Im(z) = z.i

The functions Re and Im simply return the real (Re) and imaginary (Im) components of z.

Pow2(z) = z^2
Pow3(z) = z^3
Pow4(z) = z^4
Pow5(z) = z^5
Pow6(z) = z^6

The Pow... functions return integral powers of z. These functions are frequently included in function proxy options.

Recip(z)  = 1/z
Recip2(z) = 1/z^2
Recip3(z) = 1/z^3
Recip4(z) = 1/z^4
Recip5(z) = 1/z^5
Recip6(z) = 1/z^6

The Recip... functions return reciprocals of integral powers of z. These functions are frequently included in function proxy options.

Sqrt(z)  = square root of z
Root3(z) = z^(1/3) = Root(z, 3, 0)
Root4(z) = z^(1/4) = Root(z, 4, 0)
Root5(z) = z^(1/5) = Root(z, 5, 0)
Root6(z) = z^(1/6) = Root(z, 6, 0)

Sqrt(z) returns the principle square root of z. The Root... functions return principle root of z^(1/N), where N is given in the name. These functions are frequently included in function proxy options.

Root(z, power, k) = k-th root of z^(1/power)

Root returns the kth root of z^(1/power). The values k and power are integers where 0 <= k < power. The principle root is given by k=0.

Conj(z)    = Complex(z.r, -z.i)
Flip(z)    = Complex(z.i, z.r)
Abs(z)     = Sqrt(z.r^2 + z.i^2)
Arg(z)     = radian angle of the point z
Atan2(y,x) = Arg(Complex(x, y))
AbsSqr(z)  = z.r^2 + z.i^2
AbsX(z)    = Complex(Abs(z.r), z.i)
AbsY(z)    = Complex(z.r, Abs(z.i))
AbsXY(z)   = Complex(Abs(z.r), Abs(z.i))

Conj(z) returns the complex conjugate of the complex argument z. Flip(z) interchanges the real and imaginary components of z. Abs(z) returns the absolute value of the complex argument z. This is the length of the vector from the origin to the point z and is sometimes referred to as the magnitude of z. If Abs(z) is applied to a real number (i.e., z.i=0), Abs(z) equals z if z is positive or -z if z is negative. Arg(z) is used to find the radian angle of a vector from the origin to the point z. The resulting value is -Math.PI < Arg(z) <= Math.PI. Atan2(y,x) is the radian angle of a vector from the origin to the point (x,y). Note the order of the arguments; y is 1st, x is 2nd. AbsSqr(z) is the same as Abs(z)^2 but is more efficient to compute. AbsX(z) applies the Abs function to the real component of z (z.r) and returns the resulting value. AbsY(z) applies the Abs function to the imaginary component of z (z.i) and returns the resulting value. AbsXY(z) applies the Abs function to both the real and imaginary components of z individually, and returns the resulting value.

ResetAbs(z, magnitude)
ResetArg(z, angle)

ResetAbs(z,magnitude) returns the complex number formed by resetting the magnitude of z to the given magnitude. ResetArg(z,angle) returns the complex number formed by resetting the angle of z to the given angle.

MulXY(z1,z2)   = Complex(z1.r*z2.r, z1.i*z2.i)
DivXY(z1,z2)   = Complex(z1.r/z2.r, z1.i/z2.i)

MulXY(z) returns the complex number formed by multiplying the real and imaginary components of z1 and z2 as shown above. DivXY(z) returns the complex number formed by dividing the real and imaginary components of z1 and z2 as shown above.

CoordX(z)       = z.x
CoordY(z)       = z.y
CoordAddXY(z)   = z.x + z.y
CoordSubXY(z)   = z.x - z.y
CoordSubYX(z)   = z.y - z.x
CoordMulXY(z)   = z.x * z.y
CoordDivXY(z)   = z.x / z.y
CoordDivYX(z)   = z.y / z.x

These functions return a value based on the associated computation shown above.

Cis(z) = Math.E^(1i*z)
Exp(z) = Math.E^z
Log(z) = natural log of z

If the argument to Cis is a radian angle A, Cis(A) is the point on the unit circle, such that a vector from the origin to the point makes an angle of A with the X axis moving counterclockwise. This function is very useful in many geometric applications. A typical scenario multiplies a point z by Cis(A) to rotate z about the origin by A radians counterclockwise. Exp(z) returns Math.E raised to the power z. Log(z) returns the natural log of z.

Dot(p, q) = p.x*q.x + p.y*q.y

Dot(p,q) returns the dot product of the 2 points p and q.

Min(a, b)  = IIf(a < b, a, b)
Max(a, b)  = IIf(a > b, a, b)
Cmin(a, b) = IIf(Abs(a) < Abs(b), a, b)
Cmax(a, b) = IIf(Abs(a) > Abs(b), a, b)

Min and Max return the minimum and maximum of the 2 arguments which are assumed to be floats. Cmin and Cmax return the minimum and maximum of the 2 complex arguments based on their magnitudes.

Min3(a, b, c)  = minimum of a, b, c
Max3(a, b, c)  = maximum of a, b, c
Cmin3(a, b, c) = minimum of a, b, c based on their magnitudes
Cmax3(a, b, c) = minimum of a, b, c based on their magnitudes

Min3 and Max3 return the minimum and maximum of the 3 arguments which are assumed to be floats. Cmin3 and Cmax3 return the minimum and maximum of the 3 complex arguments based on their magnitudes.

Rotate90(z)                     = Complex(-z.i,  z.r )
Rotate180(z)                    = Complex(-z.r, -z.i )
Rotate270(z)                    = Complex( z.i, -z.r )
ReflectAboutXAxis(z)            = Complex( z.r, -z.i )
ReflectAboutYAxis(z)            = Complex(-z.r,  z.i )
ReflectAboutPositiveDiagonal(z) = Complex( z.i,  z.r )
ReflectAboutNegativeDiagonal(z) = Complex(-z.i, -z.r )

The above functions can be used to form various permutations of the +/- real and +/- imaginary components of a complex number. Rotate90, Rotate180, and Rotate270 rotate z by 90, 180, and 270 degrees counterclockwise about the origin. ReflectAboutXAxis and ReflectAboutYAxis reflect z about the X and Y axis. ReflectAboutPositiveDiagonal and ReflectAboutNegativeDiagonal reflect z about the lines y=x and y=-x, respectively. ReflectAboutUnitCircle reflects z about a circle centered at the origin with radius 1.

Rotate30(z)
Rotate45(z)
Rotate60(z)
Rotate90(z)
Rotate120(z)
Rotate135(z)
Rotate150(z)
Rotate180(z)
Rotate210(z)
Rotate225(z)
Rotate240(z)
Rotate270(z)
Rotate200(z)
Rotate315(z)
Rotate330(z)

The above functions rotate z by the given number of degrees counterclockwise about the origin.

Reflect0(z)
Reflect30(z)
Reflect45(z)
Reflect60(z)
Reflect90(z)
Reflect120(z)
Reflect135(z)
Reflect150(z)

The above functions reflect z in a line through the origin, inclined the given number of degrees counterclockwise about the origin.

Round(r)   = round to closest integer
Int(r)     = truncate down to integer
Fix(r)     = truncate towards 0 to integer
Floor(r)   = largest integer <= to r
Ceiling(r) = smallest integer >= to r
Sign(r)    = IIf(r < 0, -1, 1)

The above functions provide the standard functions for rounding numbers to integral values, truncating numbers to integral values, and evaluating the sign of a number. Normally, argument r is a float and the return value is an integer. However, with the exception of Sign, these functions can be passed a complex value and the function is applied independently to both the real and imaginary components resulting in a complex result. This is rarely used.

Floor and Int are identical. Both are provided for historical reasons.

LShift(mask, shift) = mask shifted shift bits to the left
RShift(mask, shift) = mask shifted shift bits to the right

The above functions provide left/right shift operations. Both mask and shift are integers and shift should be less than or equal to 31.

IsInfinity(z)            = True if z.r or z.i is Infinity
IsNaN(z)                 = True if z.r or z.i is NaN
IsEven(r)                = True if r is even
IsOdd(r)                 = True if r is odd
IsZero(z)                = True if |z.r| < 1e-12 and |z.i| < 1e-12
IsEqual(z1,z2)           = IsZero(z1-z2)
IsInRange(r,rmin,rmax)   = True if rmin <= r <= rmax
IsInBox(z,center,radius) = True if z is in square given by center/radius
IsReal(z)                = True if z.i = 0
IsInteger(z)             = True if IsReal(z) && IsEqual(z, Round(z))

IsInfinity returns True if either component of z is Infinity. IsNaN returns True if either component of z is NaN. IsEven and IsOdd take an integer argument and return True if the argument is even/odd, respectively. IsZero returns True if both z.r and z.i are very close to 0. IsEqual returns True if z1 is very close to z2. IsInRange returns True if r is between rmin and rmax inclusive. IsInBox returns True if z is in the square defined by center and radius. IsReal returns True if z.i is 0. IsInteger returns True if z is very close to an integer value. Use Round(z) if you need the exact integer value.

ComplexToPolar(z) = Polar(Abs(z), Arg(z)) ' convert complex z to polar
PolarToComplex(p) = p.r*Cis(p.a)          ' convert polar p to complex

ComplexToPolar and PolarToComplex change a complex value to/from its polar representation.

NormalizeAngle(radian) = angle, 0 <= angle < 2*Math.PI
SectorIndex(angle, count) = index, 0 <= index < count

DegreeToRadian and RadianToDegree convert an angle between degree and radian forms. That is, given an angle A in degrees, DegreeToRadian(A) is the equivalent angle given in radians. Given an angle A in radians, RadianToDegree(A) is the equivalent angle given in degrees. NormalizeAngle converts a radian angle into an equivalent radian angle in the range 0 <= angle < 2*Math.PI. SectorIndex returns the sector index for the given angle based on count sectors. The returned value is in the range 0 <= index < count.

Sin(z)      = sine
Cos(z)      = cosine
Tan(z)      = tangent
Sec(z)      = secant
Csc(z)      = cosecant
Cot(z)      = cotangent
Asin(z)     = inverse sine (range: -PI/2 to PI/2 in X)
Acos(z)     = inverse cosine (range: 0 to PI in X)
Atan(z)     = inverse tangent (range: -PI/2 to PI/2 in X)
Asec(z)     = inverse secant (range: 0 to PI in X)
Acsc(z)     = inverse cosecant (range: -PI/2 to PI/2 in X)
Acot(z)     = inverse cotangent (range: -PI/2 to PI/2 in X)
Versin(z)   = 1-Cos(z)
Covers(z)   = 1-Sin(z)
Haversin(z) = Versin(z)/2
Hacovers(z) = Covers(z)/2
Sinc(z)     = IIf(z=0, 1, Sin(z)/z)
Tanc(z)     = IIf(z=0, 1, Tan(z)/z)
Arsh(z)     = Asin(1i*z)/1i
Arch(z)     = Acos(z)*1i
Arth(z)     = Atan(1i*z)/1i

These are standard trigonometric functions.

For additional details see:

Eric W. Weisstein. "Trigonometric Functions."

From MathWorld--A Wolfram Web Resource.

Eric W. Weisstein. "Versine."

From MathWorld--A Wolfram Web Resource.

Eric W. Weisstein. "Coversine."

From MathWorld--A Wolfram Web Resource.

Eric W. Weisstein. "Haversine."

From MathWorld--A Wolfram Web Resource.

Eric W. Weisstein. "Sinc Function."

From MathWorld--A Wolfram Web Resource.

Eric W. Weisstein. "Tanc Function."

From MathWorld--A Wolfram Web Resource.

Eric W. Weisstein. "Arsh."

From MathWorld--A Wolfram Web Resource.

Eric W. Weisstein. "Arch."

From MathWorld--A Wolfram Web Resource.

Eric W. Weisstein. "Arth."

From MathWorld--A Wolfram Web Resource.

Sinh(z)      = hyperbolic sine
Cosh(z)      = hyperbolic cosine
Tanh(z)      = hyperbolic tangent
Sech(z)      = hyperbolic secant
Csch(z)      = hyperbolic cosecant
Coth(z)      = hyperbolic cotangent
Asinh(z)     = inverse hyperbolic sine (range: -PI/2 to PI/2 in Y)
Acosh(z)     = inverse hyperbolic cosine (range: 0 to PI in Y)
Atanh(z)     = inverse hyperbolic tangent (range: -PI/2 to PI/2 in Y)
Asech(z)     = inverse secant (range: 0 to PI in Y)
Acsch(z)     = inverse cosecant (range: -PI/2 to PI/2 in Y)
Acoth(z)     = inverse cotangent (range: -PI/2 to PI/2 in Y)
Versinh(z)   = 1-Cosh(z)
Coversh(z)   = 1-Sinh(z)
Haversinh(z) = Versinh(z)/2
Hacoversh(z) = Coversh(z)/2
Sinhc(z)     = IIf(z=0, 1, Sinh(z)/z)
Tanhc(z)     = IIf(z=0, 1, Tanh(z)/z)

These are standard hyperbolic functions.

For additional details see:

Eric W. Weisstein. "Hyperbolic Functions."

From MathWorld--A Wolfram Web Resource.

Eric W. Weisstein. "Sinhc Function."

From MathWorld--A Wolfram Web Resource.

Eric W. Weisstein. "Tanhc Function."

From MathWorld--A Wolfram Web Resource.

InverseSin(z)     = inverse sine
InverseCos(z)     = inverse cosine
InverseTan(z)     = inverse tangent
InverseSec(z)     = inverse secant
InverseCsc(z)     = inverse cosecant
InverseCot(z)     = inverse cotangent

InverseSinh(z)    = inverse hyperbolic sine
InverseCosh(z)    = inverse hyperbolic cosine
InverseTanh(z)    = inverse hyperbolic tangent
InverseSech(z)    = inverse secant
InverseCsch(z)    = inverse cosecant
InverseCoth(z)    = inverse cotangent

These are alternate versions of the inverse trigonometric functions and inverse hyperbolic functions. The standard inverse trigonometric functions return values whose range in X (Y for the inverse hyperbolic functions) differs based on the given function. In addition the standard inverse trigonometric functions are not periodic. For example, Acos(z) ranges in X from 0 to Math.PI so if you need a larger range in X you need to rotate by Math.PI about 0 to extend the range to -Math.PI to Math.PI and then you can extend it further by translating in X by +/-2*Math.PI. These functions normalize the range to -Math.PI to Math.PI in X (Y for the hyperbolic functions) and have a period of 2*Math.PI so you can extend the range further by translating in X (Y for the hyperbolic trig functions) by +/-2*Math.PI.

Scale(z, factor)  = z scaled by factor
Rotate(z, angle)  = z rotated by angle given in radians
Reflect(z, angle) = z reflected in line sloped angle radians

The above functions transform the value z and return the result. Scale(z,factor) scales z by factor. If factor.y is not equal to 0, the function scales z independently in X and Y using factors factor.x and factor.y, respectively. Rotate(z,angle) rotates z counterclockwise about the origin by angle, given in radians. Reflect(z,angle) reflects z about a line through the origin inclined at angle radians (counterclockwise) relative to the X axis.

Bounce(r)            = bounce value in range 0 to 1
Clip(r)              = clip value to range 0 to 1
ClipValue(r, x)      = clip value to range 0 <= value <= x
ClipToRange(r, x, y) = clip value to range x <= value <= y
Wrap(r)              = wrap value to range 0 to 1
WrapIndex(r, n)      = wrap integer index r to range 0 to n-1
WrapValue(r, x)      = wrap value to range 0 <= value < x
WrapToRange(r, x, y) = wrap value to range x <= value < y
Smooth(r)            = 0.5 * (1 - Cos(Math.PI * r))
SmoothBounce(r)      = 0.5 * (1 - Cos(2 * Math.PI * r))

These functions transform the value r and return the result. The value r is assumed to be float unless otherwise stated. Bounce(r) leaves r values from 0 to 1 unchanged, values from 1 to 2 are mapped to 1 to 0, values from 2 to 3 are mapped to 0 to 1, values from 3 to 4 are mapped to 1 to 0, etc. Typically, Bounce is used impose a cyclic structure onto non-cyclic data. Clip(r) clips r values outside the range 0 to 1. That is, Clip returns 0 given any value less than 0, and returns 1 given any value greater than 1. ClipValue(r) clips r values outside the range 0 to x. That is, ClipValue returns 0 given any value less than 0, and returns x given any value greater than x. ClipToRange(r,x,y) clips r values outside the range x to y. That is, ClipToRange returns x given any value less than x, and returns y given any value greater than y. Wrap(r) wraps r values outside the range 0 to 1. For example, Wrap(1.1) returns 0.1, Wrap(1.6) returns 0.6, and Wrap(-0.2) returns 0.8. WrapIndex(r,n) wraps integer values such that the return value is between 0 and n-1, inclusive. WrapValue(r,x) wraps values such that the return value is greater than or equal to 0 and less than x. WrapToRange(r,x,y) wraps values such that the return value is greater than or equal to x and less than y.  Smooth(r) and SmoothBounce(r) use the cosine function to smooth the input data as shown above.

Tent(r, period, shift)
Ramp(r, period, shift)

Tent(r,period,shift) maps a value r into the range 0 to 1. If period is 1 and shift is 0, as r ranges from 0 to 0.5, the function ranges from 0 to 1. As r ranges from 0.5 to 1, the function ranges from 1 to 0. Period changes the period over which the function moves from 0 to 1 and back again. Shift, given as a percent of period, shifts the curve, left or right. For example, if period is 4 and shift is 0.5, as r ranges from 0 to 2, the function ranges from 1 to 0, and as r ranges from 2 to 4, the function ranges from 0 to 1.

Ramp(r,period,shift) maps a value r into the range 0 to 1. If period is 1 and shift is 0, as r ranges from 0 to 1, the function ranges from 0 to 1. As r ranges from 1 to 2, the function ranges from 0 to 1, and so on. Period changes the period over which the function moves from 0 to 1. Shift, given as a percent of period, shifts the curve, left or right.

In both functions, all three arguments are floats, period is greater than 0, and shift is between 0 and 1, inclusive.

Bucket(r, n)

Bucket(r,n) returns an integer between 0 and n-1 based on r which is assumed to be a value between 0 and 1. If r is outside the range 0 to 1, it is wrapped around into this range before computing the bucket index.

Blend(p, q, r)       = p + (q - p) * r
SmoothBlend(p, q, r) = Blend(p, q, (1-Math.Cos(r*Math.PI))/2)

Blend(p,q,r) returns a point on the line defined by p and q based on r which is usually a value between 0 and 1. If r is in the range 0 to 1, the returned point is between p and q at a distance from p proportional to r. SmoothBlend(p,q,r) is identical to Blend(p,q,r) but the blending value r is smoothed using the cosine function.

LRFold(r, v) = IIf(r < v, 2*v-r, r)
RLFold(r, v) = IIf(r > v, 2*v-r, r)

LRFold(r,v) returns r reflected about v if r<v and returns r if r>v. RLFold(r,v) returns r reflected about v if r>v and returns r if r<v. Both r and v are floats.

BoxFold(z, center, radius) = Complex( \
BoxFold(z.r, center.r, radius), \
BoxFold(z.i, center.i, radius) \
)

BoxFold(r,center,radius) returns r reflected about (center-radius) if r<(center-radius) or if r>(center+radius), and returns r otherwise. r, center, and radius are floats and radius is greater than 0. BoxFold(z,center,radius) returns the complex expression give above. z and center are complex numbers, and radius is a float greater than 0.

CircleFoldIn returns r reflected about the circle given by center and radius if r is outside the circle. CircleFoldOut returns r reflected about the circle given by center and radius if r is inside the circle.

DistanceMetric(type, power, z)

DistanceMetric applies the distance metric given by the argument type and the result is raised to the given power. The different types are defined in an enum called DistanceMetricTypes as shown below:

#define DistanceMetricTypes

enum DistanceMetricTypes {
X2addY2,       "X^2 + Y^2"
X2,            "X^2"
Y2,            "Y^2"
MinX2Y2,       "Min( X^2, Y^2 )"
MaxX2Y2,       "Max( X^2, Y^2 )"
MinAbsXAbsY,   "Min( |X|, |Y| )"
MaxAbsXAbsY,   "Max( |X|, |Y| )"
AbsXaddAbsY2,  "( |X| + |Y| )^2"
AbsXsubAbsY2,  "( |X| - |Y| )^2"
AbsXaddAbsY,   "Abs( |X| + |Y| )"
AbsXsubAbsY,   "Abs( |X| - |Y| )"
AbsX3addAbsY3, "Abs( |X^3| + |Y^3| )"
AbsX3subAbsY3, "Abs( |X^3| - |Y^3| )"
X2subY2,       "Abs( X^2 - Y^2 )"
XmulY,         "Abs( X * Y )"
}
#end

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