Vector and Matrix Utils #93

Parent #79Owner #36Flags readSource RPG Core/rpgcore-patched.db

Aliases: Vector and Matrix Utils, vector, matrix

28 verbs · 7 properties · 0 children

Verbs

VerbSpecFlagsDefinerLines
vector_add vector_sub vector_mul vector_divthis none thisrxd#9357
matrix_add matrix_subthis none thisrxd#9317
transposethis none thisrxd#9312
determinantthis none thisrxd#9338
inversethis none thisrxd#9318
identitythis none thisrxd#9311
nullthis none thisrxd#9314
is_squarethis none thisrxd#933
is_nullthis none thisrxd#9313
is_identitythis none thisrxd#9313
cross_prod outer_prod vector_prodthis none thisrxd#9331
norm lengththis none thisrxd#938
submatrixthis none thisrxd#9316
dot_prod inner_prod scalar_prodthis none thisrxd#9319
dimension*sthis none thisrxd#936
orderthis none thisrxd#932
scalar_vector_add scalar_vector_sub scalar_vector_mul scalar_vector_divthis none thisrxd#9331
subtended_anglethis none thisrxd#9311
columnthis none thisrxd#938
matrix_multhis none thisrxd#9319
scalar_matrix_mul scalar_matrix_divthis none thisrxd#9326
is_matrixthis none thisrxd#9312
is_vectorthis none thisrxd#9313
is_reflexive is_areflexivethis none thisrxd#9316
is_symmetric is_asymmetricthis none thisrxd#9318
is_transitive is_atransitivethis none thisrxd#9324
_relation_resultthis none thisrxd#9310
is_partial_orderingthis none thisrxd#933

Properties

PropertyDefinerFlagsOwnerValue
note#93rc#36"Please contact Uther@LambdaMOO if you make changes to this object, so he can make the changes on Lambda and elsewhere."
help_msg#79rc#36
list of 62{"Utility verbs for manipulating lists as vectors (one dimensional lists) or as matrices (two dimensional lists).", "", "Some definitions:", "A VECTOR is a list of INTs or a list of FLOATs. Each element in the list represents the vector's cartesian coordinate as measured from its tail to its tip. (For instance, {3, 4} represents a vector in the x-y plane with an x component of 3 and a y component of 4. {-2, 5, 10} represents a vector in 3-space with a x component of -2, a y component of 5 and a z component of 10.)", "A MATRIX is a list of VECTORs, all of which have the same number (and type) of components.", "", "Vector verbs:", ":vector_add (V1 [,V2 ...]) => VN such that VN[n] = V1[n] + V2[n]...", ":vector_sub (V1 [,V2 ...]) => VN such that VN[n] = V1[n] - V2[n]...", ":scalar_vector_mul (V, S) => VN such that VN[n] = V[n] * S...", ":scalar_vector_div (V, S) => VN such that VN[n] = V[n] / S...", ":dot_prod (V1, V2) => NUM sum of the products of the ", ":inner_prod corresponding elements of the two", " vectors.", ":cross_prod (V1, V2) => VN, the vector perpendicular to both V1", ":outer_prod and V2 with length equal to the area of", " the parallelogram spanned by V1 and V2.", ":subtended_angle (V1, V2) => FLOAT smallest radian angle defined by", " V1 and V2.", ":length (V) => FLOAT length of the vector. ", ":norm", "", "Matrix and Vector verbs:", ":dimensions (M) => LIST of dimensional sizes", ":order (M) => NUM of dimensions", "", "Matrix verbs:", ":matrix_add (M1 [,M2 ...]) => MN such that MN[m][n] = M1[m][n] + M2[m][n]...", ":matrix_sub (M1 [,M2 ...]) => MN such that MN[m][n] = M1[m][n] - M2[m][n]...", ":matrix_mul (M1, M2) => MN such than MN[m][n] = the dot product of the ", " mth row of M1 and the nth column of M2.", ":scalar_matrix_mul (M, S) => MN such that MN[m][n] = M[m][n] * S...", ":scalar_matrix_div (M, S) => MN such that MN[m][n] = M[m][n] / S...", ":transpose (M1) => M2 such that the rows in M1 are the columns in", " M2 and vice versa.", ":identity (INT <size>) => Identity matrix (I) of dimensions <size> by ", " <size>.", ":null (INT <size>) => Null matrix (O) of dimensions <size> by <size>.", ":is_square (M) => 1 iff dimensions of M are equal.", ":column (M, INT <n>) => LIST the nth column of M.", "", "Square Matrix verbs:", ":determinant (M) => NUM the determinant of the square matrix.", ":inverse (M) => the matrix that M multiplied by :inverse(M) yields I.", ":is_identity (M) => 1 iff M is I.", ":is_null (M) => 1 iff M is O.", "", "Relation verbs:", ":is_reflexive (M) => 1 if M is a reflexive relation, -1 if areflexive,", " 0 otherwise.", ":is_areflexive (M) => 1 if M is an areflexive relation, -1 if reflexive,", " 0 otherwise.", ":is_symmetric (M) => 1 if M is a symmetric relation, -1 if asymmetric,", " 0 otherwise.", ":is_asymmetric (M) => 1 if M is an asymmetric relation, -1 if symmetric,", " 0 otherwise.", ":is_transitive (M) => 1 if M is a transitive relation, -1 if atransitive,", " 0 otherwise.", ":is_atransitive (M) => 1 if M is an atransitive relation, -1 if transitive,", " 0 otherwise.", ":is_partial_ordering (M) => 1 if M is a reflexive, asymmetric, transitive", " relation."}
key#1c#360
aliases#1rc#36{"Vector and Matrix Utils", "vector", "matrix"}
description#1rc#36"This is a utilities package for dealing with lists as representations of vectors and matrices. Type `help $matrix_utils' for more details."
object_size#1r#36{32045, -1090650497}
html#1rc#36<clear>

Ancestry

Ancestors (nearest first): #79 Generic Utilities Package#1 Root Class

Children: none

Call graph

calls n93_1 #93:matrix_add n55_16 #55:slice n93_1->n55_16 n93_2 #93:transpose n93_21 #93:is_matrix n93_2->n93_21 n93_18 #93:column n93_2->n93_18 n93_22 #93:is_vector n93_21->n93_22 n93_3 #93:determinant n93_3->n93_3 n93_7 #93:is_square n93_3->n93_7 n93_12 #93:submatrix n93_3->n93_12 n93_7->n93_21 n93_15 #93:order n93_7->n93_15 n93_4 #93:inverse n93_4->n93_3 n93_4->n93_12 n26_3 #26:pow n93_4->n26_3 n93_5 #93:identity n93_6 #93:null n93_5->n93_6 n93_8 #93:is_null n93_8->n93_7 n93_9 #93:is_identity n93_9->n93_7 n93_10 #93:cross_prod n93_10->n93_3 n93_10->n93_12 n93_10->n93_22 n93_11 #93:norm n93_11->n93_22 n93_13 #93:dot_prod n93_11->n93_13 n93_13->n93_22 n93_0 #93:vector_add n93_13->n93_0 n93_16 #93:scalar_vector_add n93_16->n93_22 n93_17 #93:subtended_angle n93_17->n93_22 n93_17->n93_11 n93_17->n93_13 n93_19 #93:matrix_mul n93_19->n93_21 n93_19->n93_18 n93_19->n93_13 n93_20 #93:scalar_matrix_mul n93_20->n93_21 n93_23 #93:is_reflexive n93_23->n93_7 n93_26 #93:_relation_result n93_23->n93_26 n93_24 #93:is_symmetric n93_24->n93_7 n93_24->n93_26 n93_25 #93:is_transitive n93_25->n93_7 n93_25->n93_26 n93_27 #93:is_partial_ordering n93_27->n93_23 n93_27->n93_24 n93_27->n93_25

Source

vector_add vector_sub vector_mul vector_div

Spec this none thisFlags rxdOwner #36Definer #93

Referenced by

Source

1":vector_add(V1 [,V2 ...]) => VN such that VN[n] = V1[n] + V2[n]...";
2":vector_sub(V1 [,V2 ...]) => VN such that VN[n] = V1[n] - V2[n]...";
3":vector_mul(V1 [,V2 ...]) => VN such that VN[n] = V1[n] * V2[n]...";
4":vector_div(V1 [,V2 ...]) => VN such that VN[n] = V1[n] / V2[n]...";
5"Vectors do not need to be the same length, but they should be. VN's length will be the length of the longest vector in the arguments. :vector_add and :vector_sub will pad out the smaller vectors with 0's or 0.0's. :vector_mul and :vector_div will pad out the smaller vectors with 1's or 1.0's. Vectors do not need to contain homogeneous data, but the nth term of each vector must be of the same type.";
6"I can see a reason for wanting to do vector addition or subtraction, but multiplication and divareion is usually handled in other ways. I've included them here for novelty, and becuase it was easy enough to do.";
7"";
8"Vector addition is used when two or more similar vector quantities are at work and need to be resolved into a single vector. For instance, a ship travelling in a current will be acted upon by (at least) two forces: a force propelling it forward (its engine), and a force pushing it off course (the current). The sum of these two forces gives the resultant net force acting upon the ship and, since Force = Mass * Acceleration, the direction the ship is accelerating.";
9"";
10"Vector subtraction can be used to reverse the process of vector addition. In the ship problem above, let's say the actual resultant force is known, but it does not match the result of adding the propelling force and the drifting force. Friction is probably acting against the motion of the ship. Subtracting the computed resultant force from the known net force will yield the frictional force acting against the progress of the ship.";
11"";
12"Vector multiplication and division do not have RL examples, but vector multiplication of this type makes computing the dot product of two vectors simple.";
13"";
14if (length(args) == 1)
15return args;
16elseif (!args)
17return raise(E_INVARG);
18endif
19type = verb[$ - 2..$];
20lresult = max = length(args[1]);
21results = args[1];
22for n in [2..length(args)]
23if (type == "add")
24for m in [1..min(lcurr = length(args[n]), lresult)]
25results[m] = results[m] + args[n][m];
26endfor
27if (lcurr > lresult)
28results[lresult + 1..lcurr] = args[n][lresult + 1..lcurr];
29endif
30elseif (type == "sub")
31for m in [1..min(lcurr = length(args[n]), lresult)]
32results[m] = results[m] - args[n][m];
33endfor
34if (lcurr > lresult)
35for m in [lresult + 1..lcurr]
36results = {@results, -args[n][m]};
37endfor
38endif
39elseif (type == "mul")
40for m in [1..min(lcurr = length(args[n]), lresult)]
41results[m] = results[m] * args[n][m];
42endfor
43if (lcurr > lresult)
44results[lresult + 1..lcurr] = args[n][lresult + 1..lcurr];
45endif
46else
47for m in [1..min(lcurr = length(args[n]), lresult)]
48results[m] = results[m] / args[n][m];
49endfor
50if (lcurr > lresult)
51for m in [lresult + 1..lcurr]
52results = {@results, (typeof(foo = args[n][m]) == INT) ? 1 / foo | (1.0 / foo)};
53endfor
54endif
55endif
56endfor
57return results;

matrix_add matrix_sub

Spec this none thisFlags rxdOwner #36Definer #93

Referenced by

none

Source

1":matrix_add(M1 [, M2 ...]) => MN such that MN[m][n] = M1[m][n] + M2[m][n]...";
2":matrix_sub(M1 [, M2 ...]) => MN such that MN[m][n] = M1[m][n] - M2[m][n]...";
3"Matrices should all be of the same size.";
4"";
5"Matrix addition and subtraction is simply the addition or subtraction of the vectors contained in the matrices. See 'help $matrix_utils:vector_add' for more help.";
6type = verb[$ - 2..$];
7results = args[1];
8if (typeof(results[1][1]) == LIST)
9for n in [1..length(results)]
10results[n] = this:(verb)(results[n], @$list_utils:slice(args[2..$], n));
11endfor
12else
13for n in [1..length(results)]
14results[n] = this:("vector_" + type)(results[n], @$list_utils:slice(args[2..$], n));
15endfor
16endif
17return results;

transpose

Spec this none thisFlags rxdOwner #36Definer #93

Referenced by

none

Source

1":transpose(Mmn) => Mnm";
2"Transpose an m by n matrix into an n by m matrix by making the rows in the original the columns in the output.";
3{mat} = args;
4if (!this:is_matrix(mat))
5return raise("E_INVMAT", "Invalid Matrix Format");
6endif
7j = this:dimensions(mat)[2];
8result = {};
9for n in [1..j]
10result = {@result, this:column(mat, n)};
11endfor
12return result;

determinant

Spec this none thisFlags rxdOwner #36Definer #93

Referenced by

Source

1":determinant(M) => NUM the determinant of the matrix.";
2"";
3"There are several properties of a matrix's determinant. Adding or subtracting a row or column from another row or colum of a matrix does not hange the value of its determinant. Multiplying a row or column of a matrix by a single scalar value has the effect of multiplying the matrix's determinant by the same scalar.";
4"";
5"However, the most dramatic use of determinants is in solving linear equations. For example, the solution to this system of equations:";
6"";
7"Ax1 + Bx2 + Cx3 = D";
8"Ex1 + Fx2 + Gx3 = H";
9"Ix1 + Jx2 + Kx3 = L";
10"";
11"is";
12"";
13"     1 |D B C|         1 |A D C|        1 |A B D|";
14"x1 = - |H F G|    x2 = - |E H G|   x3 = - |E F H|";
15"     Z |L J K|         Z |I L K|        Z |I J L|";
16"";
17"          |A B C|";
18"where Z = |E F G|";
19"          |I J K|";
20"";
21"or, in other words, x1, x2, and x3 are some determinant divided by Z, another determinant.";
22"";
23"Determinants are also used in computing the cross product of two vectors. See 'help $matrix_utils:cross_prod' for more info.";
24"";
25{mat} = args;
26if (!this:is_square(mat))
27return raise("E_INVMAT", "Invalid Matrix Format");
28elseif (this:dimensions(mat)[1] == 2)
29return (mat[1][1] * mat[2][2]) - (mat[1][2] * mat[2][1]);
30else
31result = 0;
32coeff = 1;
33for n in [1..length(mat[1])]
34result = result + ((coeff * mat[1][n]) * this:determinant(this:submatrix(1, n, mat)));
35coeff = -coeff;
36endfor
37return result;
38endif

inverse

Spec this none thisFlags rxdOwner #36Definer #93

Referenced by

none

Source

1":inverse(M) => MN such that M * MN = I";
2"";
3"The inverse of a matrix is very similar to the reciprocal of a scalar number. If two numbers, A and B, equal 1 (the scalar identity number) when multiplied together (AB=1), then B is said the be the reciprocal of A, and A is the reciprocal of B. If A and B are matrices, and the result of multiplying them togeter is the Identity Matrix, then B is the inverse of A, and A is the inverse of B.";
4"";
5"Computing the inverse involves the solutions of several linear equations. Since linear equations can be easily solved with determinants, this is rather simple. See 'help $matrix_utils:determinant' for more on how determinants solve linear equations.";
6"";
7{mat} = args;
8{i, j} = this:dimensions(mat);
9det = this:determinant(mat);
10result = {};
11for k in [1..i]
12sub = {};
13for l in [1..j]
14sub = {@sub, (tofloat($math_utils:pow(-1, i + j)) * this:determinant(this:submatrix(j, i, mat))) / det};
15endfor
16result = {@result, sub};
17endfor
18return result;

identity

Spec this none thisFlags rxdOwner #36Definer #93

Referenced by

none

Source

1":identity(INT <size>) => Identity matrix (I) of dimensions <size> by <size>.";
2"All elements of I are 0, except for the diagonal elements which are 1.";
3"";
4"The Identity Matrix has the unique property such that when another matrix is multiplied by it, the other matrix remains unchanged. This is similar to the number 1. a*1 = a. A * I = A, if the dimensions of I and A are the same.";
5"";
6n = args[1];
7result = this:null(n, n);
8for i in [1..n]
9result[i][i] = 1;
10endfor
11return result;

null

Spec this none thisFlags rxdOwner #36Definer #93

Referenced by

Source

1":null(INT <size>) => Null matrix (O) of dimensions <size> by <size>.";
2"All elements of O are 0.";
3"";
4"The Null Matrix has the property that is equivalent to the number 0; it reduces the original matrix to itself. a * 0 = 0. A * N = N.";
5"";
6{m, ?n = m} = args;
7result = {};
8for i in [1..m]
9result = {@result, {}};
10for j in [1..n]
11result[i] = {@result[i], 0};
12endfor
13endfor
14return result;

is_square

Spec this none thisFlags rxdOwner #36Definer #93

Referenced by

Source

1":is_square(M) => 1 iff dimensions of M are equal to each other.";
2{m} = args;
3return (this:is_matrix(m) && (this:order(m) == 2)) && ((dim = this:dimensions(m))[1] == dim[2]);

is_null

Spec this none thisFlags rxdOwner #36Definer #93

Referenced by

none

Source

1":is_null(M) => 1 iff M is O.";
2m = length(mat = args[1]);
3if (!this:is_square(mat))
4return 0;
5endif
6for i in [1..m]
7for j in [1..m]
8if (mat[i][j] != 0)
9return 0;
10endif
11endfor
12endfor
13return 1;

is_identity

Spec this none thisFlags rxdOwner #36Definer #93

Referenced by

none

Source

1":is_identity(M) => 1 iff M is I.";
2m = length(mat = args[1]);
3if (!this:is_square(mat))
4return 0;
5endif
6for i in [1..m]
7for j in [1..m]
8if ((mat[i][j] != 0) && ((i != j) ? 1 | (mat[i][j] != 1)))
9return 0;
10endif
11endfor
12endfor
13return 1;

cross_prod outer_prod vector_prod

Spec this none thisFlags rxdOwner #36Definer #93

Referenced by

none

Source

1":cross_prod(V1, V2) => VN, the vector perpendicular to both V1 and V2 with length equal to the area of the parallelogram spanned by V1 and V2, and direction governed by the rule of thumb.";
2"";
3"If A = a1i + a2j + a3k, represented as a list as {a1, a2, a3}";
4"and B = b1i + b2j + b3k, or {b1, b2, b3}, then";
5"";
6"        |i  j  k |";
7"A x B = |a1 a2 a3| = |a2 a3|i - |a1 a3|j + |a1 a2|k";
8"        |b1 b2 b3| = |b2 b3|    |b1 b3|    |b1 b2|";
9"";
10"or, in list terms, as the list of the coefficients of i, j, and k.";
11"";
12"Note: i, j, and k are unit vectors in the x, y, and z direction respectively.";
13"";
14"The rule of thumb: A x B = C  If you hold your right hand out so that your fingers point in the direction of A, and so that you can curl them through B as you make a hitchhiking fist, your thumb will point in the direction of C.";
15"";
16"Put another way, A x B = ABsin(THETA) (A cross B equals the magnitude of A times the magnitude of B times the sin of the angle between them) This is expressed as a vector perpendicular the the A-B plane, pointing `up' if you curl your right hand fingers from A to B, and `down' if your right hand fingers curl from B to A.";
17"";
18"The cross product has many uses in physics. Angular momentum is the cross product of a particles position vector from the point it is rotating around and it's linear momentum (L = r x p). Torque is the cross product of position and Force (t = r x F).";
19"";
20{v1, v2} = args;
21if (((((l = length(v1)) != length(v2)) || (l != 3)) || (!this:is_vector(v1))) || (!this:is_vector(v2)))
22return raise("E_INVVEC", "Invalid Vector Format");
23endif
24mat = {{1, 1, 1}, v1, v2};
25coeff = 1;
26result = {};
27for n in [1..3]
28result = {@result, coeff * this:determinant(this:submatrix(1, n, mat))};
29coeff = -coeff;
30endfor
31return result;

norm length

Spec this none thisFlags rxdOwner #36Definer #93

Referenced by

Source

1":norm(V) => FLOAT";
2":length(V) => FLOAT";
3"The norm is the length of a vector, the square root of the sum of the squares of its elements.";
4"";
5"In school, we all should have learned the Pythagorean Theorem of right triangles: The sum of the squares of the sides of a right triagle is equal to the square of the hypoteneuse. The Theorem holds true no matter how many dimensions are being considered. The length of a vector is equal to the square root of the sum of the squares of its components. The dot product of a vector with itself happens to be the sum of the squares of its components.";
6"";
7{v} = args;
8return this:is_vector(v) ? sqrt(tofloat(this:dot_prod(v, v))) | E_TYPE;

submatrix

Spec this none thisFlags rxdOwner #36Definer #93

Referenced by

Source

1":submatrix(i, j, M1) => M2, the matrix formed from deleting the ith row and jth column from M1.";
2{i, j, mat} = args;
3{k, l} = this:dimensions(mat);
4result = {};
5for m in [1..k]
6sub = {};
7for n in [1..l]
8if ((m != i) && (n != j))
9sub = {@sub, mat[m][n]};
10endif
11endfor
12if (sub)
13result = {@result, sub};
14endif
15endfor
16return result;

dot_prod inner_prod scalar_prod

Spec this none thisFlags rxdOwner #36Definer #93

Referenced by

Source

1":dot_prod(V1, V2) => NUM";
2":inner_prod(V1, V2) => NUM";
3"The dot, or inner, product of two vectors is the sum of the products of the corresponding elements of the vectors.";
4"If V1 = {1, 2, 3} and V2 = {4, 5, 6}, then V1.V2 = 1*4 + 2*5 + 3*6 = 32";
5"";
6"The dot product is useful in computing the angle between two vectors, and the length of a vector. See 'help $matrix_utils:subtended_angle' and 'help $matrix_utils:length'.";
7"";
8"A . B = ABcos(THETA)  (A dot B equals the magnitude of A times the magnitude of B times the cosine of the angle between them.)";
9"";
10{v1, v2} = args;
11if ((((l = length(v1)) != length(v2)) || (!this:is_vector(v1))) || (!this:is_vector(v2)))
12return raise("E_INVVEC", "Invalid Vector Format");
13endif
14temp = this:vector_mul(v1, v2);
15result = (typeof(temp[1]) == INT) ? 0 | 0.0;
16for n in [1..l]
17result = result + temp[n];
18endfor
19return result;

dimension*s

Spec this none thisFlags rxdOwner #36Definer #93

Referenced by

none

Source

1":dimensions(M) => LIST of dimensional sizes.";
2l = {length(m = args[1])};
3if (typeof(m[1]) == LIST)
4l = {@l, @this:dimensions(m[1])};
5endif
6return l;

order

Spec this none thisFlags rxdOwner #36Definer #93

Referenced by

Source

1":order(M) => INT how many dimensions does this matrix have? 1 means vector";
2return length(this:dimensions(args[1]));

scalar_vector_add scalar_vector_sub scalar_vector_mul scalar_vector_div

Spec this none thisFlags rxdOwner #36Definer #93

Referenced by

none

Source

1":scalar_vector_add(S, V) => VN such that VN[n] = V[n] + S...";
2":scalar_vector_sub(S, V) => VN such that VN[n] = V[n] - S...";
3":scalar_vector_mul(S, V) => VN such that VN[n] = V[n] * S...";
4":scalar_vector_div(S, V) => VN such that VN[n] = V[n] / S...";
5"Actually, arguments can be (S, V) or (V, S). Each element of V is augmented by S. S should be either an INT or a FLOAT, as appropriate to the values in V.";
6"";
7"I can see a reason for wanting to do scalar/vector multiplcation or division, but addition and subtraction between vector and scalar types is not done. I've included them here for novelty, and because it was easy enough to to.";
8"";
9"Scalar-vector multiplication stretches a vector along its direction, generating points along a line. One of the more famous uses from physics is Force equals mass times acceleration. F = ma. Force and acceleration are both vectors. Mass is a scalar quantity.";
10"";
11if (typeof(args[1]) == LIST)
12{vval, sval} = args;
13else
14{sval, vval} = args;
15endif
16if (!this:is_vector(vval))
17return raise("E_INVVEC", "Invalid Vector Format");
18endif
19type = verb[$ - 2..$];
20for n in [1..length(vval)]
21if (type == "add")
22vval[n] = vval[n] + sval;
23elseif (type == "sub")
24vval[n] = vval[n] - sval;
25elseif (type == "mul")
26vval[n] = vval[n] * sval;
27else
28vval[n] = vval[n] / sval;
29endif
30endfor
31return vval;

subtended_angle

Spec this none thisFlags rxdOwner #36Definer #93

Referenced by

none

Source

1":subtended_angle(V1, V2) => FLOAT smallest angle defined by V1, V2 in radians";
2"";
3"Any two vectors define two angles, one less than or equal to 180 degrees, the other 180 degrees or more. The larger can be determined from the smaller, since their sum must be 360 degrees.";
4"";
5"The dot product of the two angles, divided by the lengths of each of the vectors is the cosine of the smaller angle defined by the two vectors.";
6"";
7{v1, v2} = args;
8if ((((l = length(v1)) != length(v2)) || (!this:is_vector(v1))) || (!this:is_vector(v2)))
9return raise("E_INVVEC", "Invalid Vector Format");
10endif
11return acos(tofloat(this:dot_prod(v1, v2)) / (this:norm(v1) * this:norm(v2)));

column

Spec this none thisFlags rxdOwner #36Definer #93

Referenced by

Source

1":column(M, INT <n>) => LIST the nth column of M.";
2{mat, i} = args;
3j = this:dimensions(mat)[1];
4result = {};
5for m in [1..j]
6result = {@result, mat[m][i]};
7endfor
8return result;

matrix_mul

Spec this none thisFlags rxdOwner #36Definer #93

Referenced by

none

Source

1":matrix_mul(M1, M2) => MN such that MN[m][n] = the dot product of the mth row of M1 and the transpose of thenth column of M2.";
2"";
3"Matrix multiplication is the most common and complex operation performed on two matrices. First, matrices can only be multiplied if they are of compatible sizes. An i by j matrix can only be multiplied by a j by k matrix, and the results of this multiplication will be a matrix of size i by k. Each element in the resulting matrix is the dot product of a row from the first matrix and a column from the second matrix. (See 'help $matrix_utils:dot_prod'.)";
4"";
5{m1, m2} = args;
6{i, j} = this:dimensions(m1);
7{k, l} = this:dimensions(m2);
8if (((j != k) || (!this:is_matrix(m1))) || (!this:is_matrix(m2)))
9return raise("E_INVMAT", "Invalid Matrix Format");
10endif
11result = {};
12for m in [1..i]
13sub = {};
14for n in [1..l]
15sub = {@sub, this:dot_prod(m1[m], this:column(m2, n))};
16endfor
17result = {@result, sub};
18endfor
19return result;

scalar_matrix_mul scalar_matrix_div

Spec this none thisFlags rxdOwner #36Definer #93

Referenced by

none

Source

1":scalar_matrix_add(S, M) => MN such that MN[m][n] = MN[m][n] + S...";
2":scalar_matrix_sub(S, M) => MN such that MN[m][n] = MN[m][n] - S...";
3":scalar_matrix_mul(S, M) => MN such that MN[m][n] = MN[m][n] * S...";
4":scalar_matrix_div(S, M) => MN such that MN[m][n] = MN[m][n] / S...";
5"Actually, arguments can be (S, M) or (M, S). Each element of M is augmented by S. S should be either an INT or a FLOAT, as appropriate to the values in M.";
6"I can see a reason for wanting to do scalar/matrix multiplication or division, but addition and subtraction between matrix and scalar types is not done. I've included them here for novelty, and because it was easy enough to do.";
7type = verb[$ - 2..$];
8if (typeof(args[1]) == LIST)
9{mval, sval} = args;
10else
11{sval, mval} = args;
12endif
13if (!this:is_matrix(mval))
14return raise("E_INVMAT", "Invalid Matrix Format");
15endif
16results = {};
17if (typeof(mval[1][1] == LIST))
18for n in [1..length(mval)]
19results = {@results, this:(verb)(mval[n], sval)};
20endfor
21else
22for n in [1..length(results)]
23results = {@results, this:("scalar_vector_" + type)(mval[n], sval)};
24endfor
25endif
26return results;

is_matrix

Spec this none thisFlags rxdOwner #36Definer #93

Referenced by

Source

1"A matrix is defined as a list of vectors, each having the smae number of elements.";
2{m} = args;
3if ((typeof(m) != LIST) || (typeof(m[1]) != LIST))
4return 0;
5endif
6len = length(m[1]);
7for v in (m)
8if ((!this:is_vector(v)) || (length(v) != len))
9return 0;
10endif
11endfor
12return 1;

is_vector

Spec this none thisFlags rxdOwner #36Definer #93

Referenced by

Source

1"A vector shall be defined as a list of INTs or FLOATs. (I'm not gonna worry about them all being the same type.)";
2flag = 1;
3{v} = args;
4if (typeof(v) != LIST)
5return 0;
6endif
7for n in (v)
8if (((ntype = typeof(n)) != INT) && (ntype != FLOAT))
9flag = 0;
10break;
11endif
12endfor
13return flag;

is_reflexive is_areflexive

Spec this none thisFlags rxdOwner #36Definer #93

Referenced by

Source

1":is_reflexive   (M) => 1 if M is a reflexive relation, -1 if areflexive,";
2"                       0 otherwise.";
3":is_areflexive does the same, but with 1 and -1 reversed.";
4{m} = args;
5if (!this:is_square(m))
6return raise("E_INVMAT", "Invalid Matrix Format");
7endif
8good = bad = 0;
9for n in [1..length(m)]
10if (!m[n][n])
11bad = 1;
12else
13good = 1;
14endif
15endfor
16return this:_relation_result(good, bad, verb[4] == "a");

is_symmetric is_asymmetric

Spec this none thisFlags rxdOwner #36Definer #93

Referenced by

Source

1":is_symmetric   (M) => 1 if M is a symmetric relation, -1 if asymmetric,";
2"                       0 otherwise.";
3":is_asymmetric does the same, but with 1 and -1 reversed.";
4{mat} = args;
5if (!this:is_square(mat))
6return raise("E_INVMAT", "Invalid Matrix Format");
7endif
8good = bad = 0;
9for m in [1..len = length(mat)]
10for n in [m + 1..len]
11if (mat[m][n] == mat[n][m])
12good = 1;
13else
14bad = 1;
15endif
16endfor
17endfor
18return this:_relation_result(good, bad, verb[4] == "a");

is_transitive is_atransitive

Spec this none thisFlags rxdOwner #36Definer #93

Referenced by

Source

1":is_transitive  (M) => 1 if M is a transitive relation, -1 if atransitive,";
2"                       0 otherwise.";
3":is_atransitive does the same, but with 1 and -1 reversed.";
4{mat} = args;
5if (!this:is_square(mat))
6return raise("E_INVMAT", "Invalid Matrix Format");
7endif
8good = bad = 0;
9for m in [1..len = length(mat)]
10for n in [1..len]
11if (mat[m][n])
12for l in [1..len]
13if (mat[n][l])
14if (mat[m][l])
15good = 1;
16else
17bad = 1;
18endif
19endif
20endfor
21endif
22endfor
23endfor
24return this:_relation_result(good, bad, verb[4] == "a");

_relation_result

Spec this none thisFlags rxdOwner #36Definer #93

Referenced by

Source

1"Common code for is_reflexive, is_symmetric, and is_transitive.";
2{good, bad, flag} = args;
3if (good && (!bad))
4result = 1;
5elseif ((!good) && bad)
6result = -1;
7else
8result = 0;
9endif
10return flag * result;

is_partial_ordering

Spec this none thisFlags rxdOwner #36Definer #93

Referenced by

none

Source

1":is_partial_ordering(M) => 1 iff M is a reflexive, asymmetric, transitive relation.";
2{mat} = args;
3return ((this:is_asymmetric(mat) == this:is_reflexive(mat)) == this:is_transitive(mat)) == 1;