Did you know ... | Search Documentation: |
Pack canny_tudor -- prolog/linear/algebra.pl |
"The introduction of numbers as coordinates is an act of violence."--Hermann Weyl, 1885-1955.
Vectors are just lists of numbers, or scalars. These scalars apply to arbitrary abstract dimensions. For example, a two-dimensional vector [1, 2] applies two scalars, 1 and 2, to dimensional units i and j; known as the basis vectors for the coordinate system.
Is it possible, advisable, sensible to describe vector and matrix operations using Constraint Logic Programming (CLP) techniques? That is, since vectors and matrices are basically columns and rows of real-numeric scalars, their operators amount to constrained relationships between real numbers and hence open to the application of CLP over reals. The simple answer is yes, the linear_algebra predicates let you express vector operators using real-number constraints.
Constraint logic adds some important features to vector operations. Suppose for instance that you have a simple addition of two vectors, a vector translation of U+V=W. Add U to V giving W. The following statements all hold true. Note that the CLP-based translation unifies correctly when W is unknown but also when U or V is unknown. Given any two, you can ask for the missing vector.
?- vector_translate([1, 1], [2, 2], W). W = [3.0, 3.0] ; false. ?- vector_translate([1, 1], V, [3, 3]). V = [2.0, 2.0] ; false. ?- vector_translate(U, [2, 2], [3, 3]). U = [1.0, 1.0] ; false.
Note also that the predicate answers non-deterministically with back-tracking until no alternative answer exists. This presumes that alternatives could exist at least in theory if not in practice. Trailing choice-points remain unless you cut them.
A matrix of M rows and N columns is an M-by-N matrix. A matrix with a single row is a row vector; one with a single column is a column vector. Because the linear_algebra module uses lists to represent vectors and matrices, you need never distinguish between row and column vectors.
Boundary cases exist. The dimensions of an empty matrix [] equals [0, _] rather than [0, 0]. And this works in reverse; the matrix unifying with dimensions [0, _] equals [].
The first list of scalars (call it a row or column) becomes 1 followed by Order-1 zeros. Subsequent scalar elements become an Order-1 identity matrix with a 0-scalar prefix for every sub-list. Operates recursively albeit without tail recursion.
Fails when matrix size Order is less than zero.
What is the difference between multiply and scale? Multiplication
multiplies two vectors whereas scaling multiplies a vector by a
scalar; hence the verb to scale. Why is the scalar at the front of
the argument list? This allows the meta-call of vector_scale(Scalar)
passing two vector arguments, e.g. when mapping lists of vectors.
The implementation performs non-deterministically because the CLP(R) library leaves a choice point when searching for alternative arithmetical solutions.
The first argument X is the exponent rather than Y, first rather
than second argument. This allows you to curry the predicate by
fixing the first exponent argument. In other words, scalar_power(2,
A, B)
squares A to B.
The following predicates are exported, but not or incorrectly documented.