FreeFlyer provides Matrix, Array, and Variable objects to allow the user to perform various mathematical operations. Many of the properties of other objects in FreeFlyer are Variable, Array, or Matrix properties. Examples of each are: Spacecraft.A (Variable), Spacecraft.Position (Array), and Spacecraft.MOI (Matrix).
This page gives an overview of working with the Variable, Array, and Matrix objects in FreeFlyer. All of the properties and methods of each of these objects are presented in detail on these pages:
Note: FreeFlyer also includes a Vector object, which can be displayed in 2D and 3D visualizations, easily determine the magnitude and direction to a specified target, and calculate intersections with ProximityZones or define custom CoordinateSystems. Vectors always have three elements, unlike an Array, which can have any number of elements. You can convert between Vectors and Arrays using syntax such as: Array1 = Vector1.Element or Vector1.Element = Array1.
Creating Variables, Arrays, and Matrices
The Variable object can be used to represent a number in FreeFlyer. Variables can be used as counters in For loops, indices in Arrays, flags for conditional control in While and If statements, combined in mathematical operations, and more. The syntax examples below show how to create Variables in FreeFlyer's FreeForm script editors.
Variable v1; // Create a Variable with a value of 0
Variable v2 = 5; // Create a Variable with a value of 5
Variable v3 = Spacecraft1.A; // Create a Variable with the value of a Spacecraft's semi-major axis
|
The Array object contains a one-dimensional set of numbers. Arrays can be used to store and manipulate data, such as through the use of various mathematical operators and functions. The examples below show some syntax options for creating Arrays.
Array a1; // Creates an Array with 10 elements
Array a2(3); // Creates an Array with 3 elements
Array a3[6]; // Creates an Array with 6 elements
Array a4 = Spacecraft1.Position; // Creates an Array with 3 elements and initializes it with the values of a Spacecraft's position
|
The Matrix object provides numerous properties and methods for calculating various matrix statistics and decompositions. FreeFlyer also supports a variety of matrix operations. These features enable users to perform many analyses in FreeFlyer, such as custom attitude modeling, without needing to interface with external programs to execute complex calculations. You can create a Matrix using any of the following syntax options. A Matrix is initialized with a particular size, but can also be resized at any time after it has been created.
Matrix m1; // Creates a 0x0 Matrix
Matrix m2[3, 3]; // Creates a 3x3 Matrix
Matrix m3(1, 5); // Creates a 1x5 Matrix
Matrix m4 = Spacecraft1.MOI; // Creates a 3x3 Matrix and initializes it with the values of a Spacecraft's moment of inertia
|
The Matrix object can only represent numeric, two-dimensional sets of data (i.e., n x n). However, you can manage multi-dimensional data by creating Lists of objects. For example, you could create a List of a List of a List of Variables to create a three dimensional set of numerical data. The syntax for creating such a List would be:
List<List<List<Variable>>> ThreeDNumericalData;
|
Variables, Arrays, and Matrices can also be created in FreeFlyer's Object Browser.
Assigning Values to Variables, Arrays, and Matrices
You can assign values to Variables, Arrays, and Matrices when they are created, or at any point in the Mission Sequence after they've been created. They can be assigned in a FreeForm script editor or using the Assignment command editor. Variables, Arrays, and Matrices can also be manipulated using various mathematical and logical operators and math functions.
It is very straightforward to assign any desired value to a Variable:
Arrays can be assigned using the syntax such as the examples shown below. Note that the definition of a virtual Array is surrounded by curly brackets, and each element is separated by a comma. Colons (:) can be used to indicate a range of elements.
a1 = {0, 1, 2, 3, 4};
a2 = Spacecraft1.Velocity;
a3 = {v1, a1, a2, 5, 6, 7};
a3.Shuffle();
a3[0:2] = Spacecraft1.Position;
a3[3:5] = Spacecraft1.Velocity;
|
You can assign the contents of a Matrix using any of the syntax options shown below. Note that the definition of a virtual Matrix is surrounded by square brackets, each element is separated by a comma, and each row is separated by a semicolon. Colons (:) can be used to indicate a range of elements.
m1 = [ 2, 4, 6;
1, 3, 5;
0, 4, 8 ];
m2.FillRandom(-5, 5);
m3 = Spacecraft1.OD.Covariance.Matrix;
m2[0:1, 1:2] = [ 9, 9;
9, 9 ];
|
Matrices can also be defined by combining Variables, Arrays, Vectors, row Matrices, column Matrices, or m x n Matrices.
Variable var = 5;
Array arr = {2, 4, 6};
Vector vec;
vec.Element = {7, 9, 1};
Matrix m5 = [ 0, arr;
var, vec ];
Matrix m6 = [Spacecraft1.Position, Spacecraft1.Velocity].Transpose();
Matrix m7;
m7.Fill(1, 3, 3);
Matrix m8 = [ 0, 0, 0, 0 ];
Matrix m9 = [ m7, [5; 5; 5];
1, 2, 3, 4 ;
m8 ];
|
Similar syntax is also available for working with StringArrays. Note that the definition of a virtual StringArray is surrounded by curly brackets, and each element is separated by a comma. Colons (:) can be used to indicate a range of elements.
StringArray sa1;
String s1 = "x";
String s2 = "y";
// Assign a StringArray with specified numbers
sa1 = {"a", "b", "c", "d", "e"};
// Assign a StringArray using another StringArray. This will grow or shrink the StringArray if necessary.
sa1 = sa1.Reverse();
// Assign a StringArray by concatenating together quoted text, String objects, and StringArrays
sa1 = {sa1, "f", "g", "h", s1};
// Assign values to a subset of elements in a StringArray. The sizes of the StringArrays on the right- and left-hand sides must match.
sa1[1:2] = {s2, "z"};
|
Accessing Values from Variables, Arrays, and Matrices
The examples below show how to access the values of Variables, Arrays, and Matrices. These objects can be used to generate output for the user, such as using the Report command as shown below, or accessed to perform other calculations. Arrays and Matrices are indexed from zero in FreeFlyer. Colons (:) can be used to indicate a range of elements.
Report v1; // Report the Variable
Report v1.ToString(); // Report the Variable as a string representation based on the magnitude of the value
Report v1.ToString("%i"); // Report the Variable as a string representation of an integer value
Report v1.ToString("%e"); // Report the Variable as a string representation of a scientific notation value
Report v1.ToString("%f"); // Report the Variable as a string representation of a floating point value
Report a3; // Report full Array
Report a3[0]; // Report first element
Report a3[2:5]; // Report elements from index 2 to index 5
Report a3[5:2]; // Report elements from index 2 to index 5 in reverse order
Report a3[:4]; // Report all elements from the beginning to index 4
Report a3[4:]; // Report all elements from index 4 to the end
Report a3.ToStringArray(); // Report the Array as a string representation based on the magnitude of the values
Report a3.ToStringArray("%i"); // Report the Array as a string representation of the integer values
Report a3.ToStringArray("%e"); // Report the Array as a string representation of the scientific notation values
Report a3.ToStringArray("%f"); // Report the Array as a string representation of the floating point values
Report a3.GetUniqueElements; // Report unique elements from the Array in the order in which they first appeared
Report m9; // Report full Matrix
Report m9[0, :]; // Report first row
Report m9[:, 0]; // Report first column
Report m9[0, 2:0]; // Report elements 0-2 of the first row in reverse order
Report m9[0:1, 0:1]; // Report top-left 2x2 elements
Report m9[:1, 0]; // Report all elements from the beginning to index 1 of the first column
Report m9[1:, 0]; // Report all elements from index 1 to the end of the first column
|
These objects can be also be reported to a file or ReportInterface, as shown below:
Report an Array to a ReportInterface:
ReportInterface ri;
Report a3[0] to ri; // Report the first element to a file
Report a3[2:5] to ri; // Report elements from index 2 to index 5 to a file
Report a3[5:2] to ri; // Report elements from index 2 to index 5 in reverse order to a file
Report a3[:4] to ri; // Report all elements from the beginning to index 4 to a file
Report a3[4:] to ri; // Report all elements from index 4 to the end to a file
Report a3.Format("%1.3e") to ri; // Report all elements of the array and format them (Scientific notation)
|
Output Report:
a3[0]
None
-3410.673000000
a3[2:5][0] a3[2:5][1] a3[2:5][2] a3[2:5][3]
None None None None
-1788.627000000 1.893006000 -1.071993000 -7.176346000
a3[5:2][0] a3[5:2][1] a3[5:2][2] a3[5:2][3]
None None None None
-7.176346000 -1.071993000 1.893006000 -1788.627000000
a3[:4][0] a3[:4][1] a3[:4][2] a3[:4][3] a3[:4][4]
None None None None None
-3410.673000000 5950.957000000 -1788.627000000 1.893006000 -1.071993000
a3[4:][0] a3[4:][1] a3[4:][2] a3[4:][3] a3[4:][4] a3[4:][5] a3[4:][6] a3[4:][7]
None None None None None None None None
-1.071993000 -7.176346000 1.893006000 -1.071993000 -7.176346000 5.000000000 6.000000000 7.000000000
a3.Format("%1.3e")
None
9.823e+01 0.000e+00 1.000e+00 2.000e+00 3.000e+00 4.000e+00 1.893e+00 -1.072e+00 -7.176e+00 5.000e+00 6.000e+00 7.000e+00
|
Report a Matrix to a ReportInterface:
ReportInterface ri;
Report m9 to ri; // Report full Matrix to a file
Report m9[0, :] to ri; // Report first row to a file
Report m9[:, 0] to ri; // Report first column to a file
Report m9[0, 2:0] to ri; // Report elements 0-2 of the first row in reverse order to a file
Report m9.Format("%1.1e") to ri; // Report all the whole matrix and format it (Scientific notation)
|
Output Report:
m9[:,0] m9[:,1] m9[:,2] m9[:,3]
None None None None
1.000000000 1.000000000 1.000000000 5.000000000
1.000000000 1.000000000 1.000000000 5.000000000
1.000000000 1.000000000 1.000000000 5.000000000
1.000000000 2.000000000 3.000000000 4.000000000
0.000000000 0.000000000 0.000000000 0.000000000
m9[0,:][:,0] m9[0,:][:,1] m9[0,:][:,2] m9[0,:][:,3]
None None None None
1.000000000 1.000000000 1.000000000 5.000000000
m9[:,0][:,0]
None
1.000000000
1.000000000
1.000000000
1.000000000
0.000000000
m9[0,2:0][:,0] m9[0,2:0][:,1] m9[0,2:0][:,2]
None None None
1.000000000 1.000000000 1.000000000
m9.Format("%1.1e")
None
1.0e+00 1.0e+00 1.0e+00 5.0e+00
1.0e+00 1.0e+00 1.0e+00 5.0e+00
1.0e+00 1.0e+00 1.0e+00 5.0e+00
1.0e+00 2.0e+00 3.0e+00 4.0e+00
0.0e+00 0.0e+00 0.0e+00 0.0e+00
|
Converting between Arrays, Matrices, Vectors, and CoordinateSystems
Several methods and shorthand notations are provided for converting between Arrays and Matrices. Please see the Literal Operators section of the Script Operators page for more information.
To convert an Array to a Matrix, the following methods are available:
// Convert an Array to a row Matrix
mat = arr.ToRowMatrix();
mat = [arr];
// Convert an Array to a column Matrix
mat = arr.ToColumnMatrix();
mat = [arr].Transpose();
// Convert an Array to a diagonal Matrix
mat = arr.ToDiagonalMatrix();
// Convert an Array to a 3-column, row-major Matrix
mat = arr.ToRowMajorMatrix(3);
// Convert an Array to a 3-row, column-major Matrix
mat = arr.ToColumnMajorMatrix(3);
|
To convert a Matrix to an Array, the following methods are available:
// Convert a Matrix to an Array, treating the the Matrix as row-major
arr = mat.ToArrayRowMajor();
arr = {mat};
// Convert a Matrix to an Array, treating the the Matrix as column-major
arr = mat.ToArrayColumnMajor();
|
You can also convert between Vectors and Arrays or Matrices using the syntax:
// Convert a Vector to an Array
arr = vec.Element;
arr = {vec};
// Convert a Vector to a Matrix
mat = [vec.Element];
mat = [vec];
// Convert an Array to a Vector
vec.Element = arr;
// Convert a Matrix to a Vector
vec.Element = {mat};
|
Similarly, you can convert a CoordinateSystem to a Matrix using the syntax:
// Convert a CoordinateSystem to a Matrix
mat = [cs];
|
Matrix Decomposition
The Matrix.Solve() method has several decomposition methods available to solve a system of linear equations written 'A * x = b' where A and b are matrices for the vector x. Requirements for individual decomposition methods are provided below.
// Househoulder QR [Requirements : None]
mat = matrix1.Solve(matrix2, 0)
// Partial Pivot LU [Requirements : Calling Matrix must be square and invertible]
mat = matrix1.Solve(matrix2, 1)
// Full Pivot LU [Requires : Calling Matrix must be square; Useful when calling Matrix is not full rank]
mat = matrix1.Solve(matrix2, 2)
// Column Pivot Householder QR [Requirements : None; Useful when calling Matrix is not full rank]
mat = matrix1.Solve(matrix2, 3)
// Full Pivot Householder QR [Requirements : None; Useful when calling Matrix is full rank]
mat = matrix1.Solve(matrix2, 4)
// LLT [Requirements : Calling Matrix must be positive definite]
mat = matrix1.Solve(matrix2, 5)
// LDLT [Requirements : Calling Matrix must be positive or negative semi-definite]
mat = matrix1.Solve(matrix2, 6)
// Jacobi SVD [Requirements : None]
mat = matrix1.Solve(matrix2, 7)
|
See Also
|