Expression templates in Eigen - eigen

I would like to understand how expression templates work in Eigen.
I understood that the sum of two dynamical double vectors is performed by something which looks like this :
CwiseBinaryOp< internal::scalar_sum_op<double>, VectorXd const, VectorXd const > operator+(VectorXd const & lhs, VectorXd const & rhs);
I also understood how the difference of two vectors is implemented.
I have two questions.
1. How does the product of a vector by a scalar work?
I have noticed that
CwiseBinaryOp< internal::scalar_product_op<double>, VectorXd const, VectorXd const >
exists but I have the feeling that it is only designed to perform componentwise operations between two vectors. Does it mean that the product of a vector by a scalar correspond to a unary operator, say
CwiseUnaryOp< internal::scalar_product_op<double>, VectorXd const, VectorXd const > ?
2. Can template expressions be built from mixed operations?
For example, in an expression like
x = u + (2*v + (v-w))
is it true that these operations are performed in a nested way like this?
v-w leads to the construction of an instance of E1
2*v leads to the construction of an instance of E2
2*v + (v-w) leads to the construction of an instance of E3
u + (2*v + (u-w)) leads to the construction of an instance of E4
x = u + (2*v + (v-w)) calls
the constructor
VectorXd(E4 const &);
or the overloading
VectorXd & operator=(E4 const &);
which evaluates the tree built from the previous steps, with the following aliases:
using diff = internal::scalar_difference_op<double>;
using prod = internal::scalar_product_op<double>;
using sum = internal::scalar_sum_op<double>;
using E1 = CwiseBinaryOp< diff, VectorXd const, VectorXd const >;
using E2 = CwiseUnaryOp< prod, VectorXd const >;
using E3 = CwiseBinaryOp< sum, E1 const, E2 const >;

1. How does the product of a vector by a scalar work?
In Eigen 3.2, it is implemented as a unary-operator, with a functor storing the value of the scalar factor. In Eigen 3.3, it is now implemented as a binary operator between the given matrix expression and a constant expression, something like:
CwiseBinaryOp<scalar_product_op<double,double>,
VectorXd,
CwiseNullaryOp<scalar_constant_op<double>, VectorXd> >
This approach permits to clearly distinguish between s*vec and vec*s, and the return type of, e.g., vec*s is equivalent to the one of vec*VectorxD::Constant(vec.size(),s).
2. Can template expressions be built from mixed operations?
Your understanding is correct: first the expressions E1 to E4 are created, then the evaluation starts from the overloaded operator= generating a code like:
for(i=0;i<x.size();++i)
x[i] = E4.coeff(i);

Related

What does the "operator <" syntax mean?

I am trying to learn C++ STL..I came across this syntax,not able to figure out what the whole line means!
struct student{
int id,pts;
bool operator < (student x) const{
return pts>x.pts;
}
}a[150000];
it is defining a "less than" operator for the struct student, so that people can write:
student one, two;
bool b = one < two;
operator < is a name to be defined, just like foo or bar. It behaves just like an identifier.
bool operator < (student x) const declares a function as bool foo (student x) const would.
The effect is to define usage of the < operator between student objects. The connection to the STL is that templates related to ordering of objects use expressions like a < b to perform the ordering. This comes up in algorithms like std::sort and containers like std::map.
That particular definition sorts students by points, which isn't a very good system for sorting students. Facilities like sort and map always provide an alternative to operator <, where you can pass a more specific function, say one called less_points. Also, since that definition of operator < uses the > operator internally (without reversing the left- and right-hand sides), it will sort in descending order whereas the usual convention is to use ascending order.
Note, it's common to define operator < or operator == without defining >, !=, or the other relational operators. The standard library only ever cares about < and ==, and boilerplate to get the rest is usually wasted. Likewise it's a good convention to avoid using relations besides < and == on objects that might not be numbers.
operator< allows comparing two students, and in this example, it compares only by pts.
struct student{
int id,pts;
bool operator < (student x) const{
return pts>x.pts; // must be pts<x.pts
}
}a[150000];
lest should it work the other way (operator >), the implementation must use operator '<'
As a good practice, please consider adding custom definition for operator > and operator=, because the comparison is based only on pts (by the definition of operator <)
For the sake of minimal completeness and logical correctness when using comparison operators, please consider adding custom definition for operators > and ==
struct student{
int id,pts;
bool operator < (student x) const{
return pts<x.pts;
}
bool operator > (student x) const{
return pts>x.pts;
}
bool operator == (student x) const{
return pts == x.pts;
}
}a[150000];

Strongly typed matrices in F#

Is it possible to create a wrapper over the F# PowerPack matrix library to create strongly typed matrices and vectors?
What I mean is I want to store the dimentionality of the matrix/vector in the type itself so that I can say
Create a function mul to multiply 2 matrices with the signature:
mul :: Matrix<float, n, m> -> Matrix<float, m, p> -> Matrix<float, n, p>
where the latter 2 arguments to the Matrix type represent the number of rows and cols and are ints.
The problem here is that n and m are values of ints, whilst type arguments need to be types.
A somewhat hackish solution would be to use a measure type for height and width. Then it could become:
mull :: Matrix<float<(H^m)*(W^n)>> -> Matrix<float<H^m*W^p>> -> Matrix<float<H^n,W^p>>
where H and W are measure types enccoding height and width respectively
[<Measure>] type H
[<Measure>] type W

How to identify the inequality involved in an arithmetic expression specified by a prolog query?

I am working on prolog and faced this scenario -
In my query, I pass something like this:
?- query( 2*X + 3*Y >= 3*Z )
Now, what I would like to do is have the prolog program capture the inequality expression so that I can have the above inequality in variables like below:
variable 'Lhs' will have 2*X + 3*Y
variable 'Rhs' will have 3*Z
Now I want the inequality involved to be also assigned somewhere (in a variable called Opr??), so that saying something like Lhs Opr Rhs would mean exactly like saying "2*X + 3*Y >= 3*Z"..
This is a general form of the scenario that I am working on. I somehow want the "inequality" involved to be identified, so that I can use it later in my code.
I am working on Eclipse-CLP with IC library.
You can do it with any prolog system, using the univ/2 operator:
parse_ops(Expr, Lhs, Rhs, Op):-
Expr =.. [Op, Lhs, Rhs].
?- parse_ops(2*X + 3*Y >= 3*Z, Lhs, Rhs, Op).
Lhs = 2*X+3*Y,
Rhs = 3*Z,
Op = (>=).
You can use univ to disassemble your inequaliy:
Eq =.. [Op,Lhs,Rhs],
This works in both directions.
This should be able to simply do:
parse_query(LHS >= RHS, LHS, RHS).
?- parse_query(2*X + 3*Y >= 3*Z, LHS, RHS).
LHS=2*X + 3*Y
RHS=3*Z
What you need to be concerned here with is order of operations the Parser uses when reading your query. Take a look at the op/3 operator for eclipse-clp and the op/3 operator doc for swi-prolog. Notice the precedence number for inequalities are higher than operators. This means that when the query (2*X +3*Y >=3*Z) is parsed, the >= operator becomes the functor. Try to use the display predicate to make this clear.
?- display(2*X + 3*Y >= 3*Z).
>=(+(*(2,X), *(3,Y)), *(3,Z))

Extending Immutable types (or: fast cache for immutable types) in OCaml

I have a recursive immutable data structure in ocaml which can be simplified to something like this:
type expr =
{
eexpr : expr_expr;
some_other_complex_field : a_complex_type;
}
and expr_expr =
| TInt of int
| TSum of (expr * expr)
| TMul of (expr * expr)
It's an AST, and sometimes it gets pretty complex (it's very deep).
there is a recursive function that evaluates an expression. For example, let's say,
let rec result expr =
match expr.eexpr with
| TInt i -> i
| TSum (e1, e2) -> result e1 + result e2
| TMul (e1, e2) -> result e1 * result e2
Now suppose I am mapping an expression to another expression, and I need to constantly check the result of an expr, sometimes more than once for the same expr, and sometimes for expressions that were recently mapped by using the pattern
{ someExpr with eexpr = TSum(someExpr, otherExpr) }
Now, the result function is very lightweight, but running it many times for a deep AST will not be very optimized. I know I could cache the value using a Hashtbl, but AFAIK the Hashtbl will only do structural equality, so it will need to traverse my long AST anyway.
I know the best option would be to include a probably immutable "result" field in the expr type. But I can't.
So is there any way in Ocaml to cache a value to an immutable type, so I don't have to calculate it eagerly every time I need it ?
Thanks!
Hash-cons the values of expr_expr. By doing this structurally equal values in your program will share exactly the same memory representation and you can substitute structural equality (=) by physical equality (==).
This paper should get you quickly started on hash-consing in OCaml.
You can use the functorial interface to control the kind of equality used by the hash table. I believe the semantics of (==) are legitimate for your purposes; i.e., if A == B then f A = f B for any pure function f. So you can cache the results of f A. Then if you find a B that's physically equal to A, the cached value is correct for B.
The downside of using (==) for hashing is that the hash function will send all structurally equal objects to the same hash bucket, where they will be treated as distinct objects. If you have a lot of structurally equal objects in the table, you get no benefit from the hashing. The behavior degenerates to a linear search.
You can't define the hash function to work with physical addresses, because the physical addresses can be changed at any time by the garbage collector.
However, if you know your table will only contain relatively few large-ish values, using physical equality might work for you.
I think you can merge the two ideas above : use hash-consing-like techniques to get the hash of the "pure expression" part of your data, and use this hash as key in the memoization table for the eval function.
Of course this only works when your eval function indeed only depends on the "pure expression" part of the function, as in the example you gave. I believe that is a relatively general case, at least if you restrict yourself to storing the successful evaluations (that won't, for example, return an error including some location information).
Edit: a small proof of concept:
type 'a _expr =
| Int of int
| Add of 'a * 'a
(* a constructor to avoid needing -rectypes *)
type pure_expr = Pure of pure_expr _expr
type loc = int
type loc_expr = {
loc : loc;
expr : loc_expr _expr;
pure : pure_expr (* or any hash_consing of it for efficiency *)
}
(* this is where you could hash-cons *)
let pure x = Pure x
let int loc n =
{ loc; expr = Int n; pure = pure (Int n) }
let add loc a b =
{ loc; expr = Add (a, b); pure = pure (Add(a.pure, b.pure)) }
let eval =
let cache = Hashtbl.create 251 in
let rec eval term =
(* for debug and checking memoization *)
Printf.printf "log: %d\n" term.loc;
try Hashtbl.find cache term.pure with Not_found ->
let result =
match term.expr with
| Int n -> n
| Add(a, b) -> eval a + eval b in
Hashtbl.add cache term.pure result;
result
in eval
let test = add 3 (int 1 1) (int 2 2)
# eval test;;
log: 3
log: 2
log: 1
- : int = 3
# eval test;;
log: 3
- : int = 3

What's the formal term for a function that can be written in terms of `fold`?

I use the LINQ Aggregate operator quite often. Essentially, it lets you "accumulate" a function over a sequence by repeatedly applying the function on the last computed value of the function and the next element of the sequence.
For example:
int[] numbers = ...
int result = numbers.Aggregate(0, (result, next) => result + next * next);
will compute the sum of the squares of the elements of an array.
After some googling, I discovered that the general term for this in functional programming is "fold". This got me curious about functions that could be written as folds. In other words, the f in f = fold op.
I think that a function that can be computed with this operator only needs to satisfy (please correct me if I am wrong):
f(x1, x2, ..., xn) = f(f(x1, x2, ..., xn-1), xn)
This property seems common enough to deserve a special name. Is there one?
An Iterated binary operation may be what you are looking for.
You would also need to add some stopping conditions like
f(x) = something
f(x1,x2) = something2
They define a binary operation f and another function F in the link I provided to handle what happens when you get down to f(x1,x2).
To clarify the question: 'sum of squares' is a special function because it has the property that it can be expressed in terms of the fold functional plus a lambda, ie
sumSq = fold ((result, next) => result + next * next) 0
Which functions f have this property, where dom f = { A tuples }, ran f :: B?
Clearly, due to the mechanics of fold, the statement that f is foldable is the assertion that there exists an h :: A * B -> B such that for any n > 0, x1, ..., xn in A, f ((x1,...xn)) = h (xn, f ((x1,...,xn-1))).
The assertion that the h exists says almost the same thing as your condition that
f((x1, x2, ..., xn)) = f((f((x1, x2, ..., xn-1)), xn)) (*)
so you were very nearly correct; the difference is that you are requiring A=B which is a bit more restrictive than being a general fold-expressible function. More problematically though, fold in general also takes a starting value a, which is set to a = f nil. The main reason your formulation (*) is wrong is that it assumes that h is whatever f does on pair lists, but that is only true when h(x, a) = a. That is, in your example of sum of squares, the starting value you gave to Accumulate was 0, which is a does-nothing when you add it, but there are fold-expressible functions where the starting value does something, in which case we have a fold-expressible function which does not satisfy (*).
For example, take this fold-expressible function lengthPlusOne:
lengthPlusOne = fold ((result, next) => result + 1) 1
f (1) = 2, but f(f(), 1) = f(1, 1) = 3.
Finally, let's give an example of a functions on lists not expressible in terms of fold. Suppose we had a black box function and tested it on these inputs:
f (1) = 1
f (1, 1) = 1 (1)
f (2, 1) = 1
f (1, 2, 1) = 2 (2)
Such a function on tuples (=finite lists) obviously exists (we can just define it to have those outputs above and be zero on any other lists). Yet, it is not foldable because (1) implies h(1,1)=1, while (2) implies h(1,1)=2.
I don't know if there is other terminology than just saying 'a function expressible as a fold'. Perhaps a (left/right) context-free list function would be a good way of describing it?
In functional programming, fold is used to aggregate results on collections like list, array, sequence... Your formulation of fold is incorrect, which leads to confusion. A correct formulation could be:
fold f e [x1, x2, x3,..., xn] = f((...f(f(f(e, x1),x2),x3)...), xn)
The requirement for f is actually very loose. Lets say the type of elements is T and type of e is U. So function f indeed takes two arguments, the first one of type U and the second one of type T, and returns a value of type U (because this value will be supplied as the first argument of function f again). In short, we have an "accumulate" function with a signature f: U * T -> U. Due to this reason, I don't think there is a formal term for these kinds of function.
In your example, e = 0, T = int, U = int and your lambda function (result, next) => result + next * next has a signaturef: int * int -> int, which satisfies the condition of "foldable" functions.
In case you want to know, another variant of fold is foldBack, which accumulates results with the reverse order from xn to x1:
foldBack f [x1, x2,..., xn] e = f(x1,f(x2,...,f(n,e)...))
There are interesting cases with commutative functions, which satisfy f(x, y) = f(x, y), when fold and foldBack return the same result. About fold itself, it is a specific instance of catamorphism in category theory. You can read more about catamorphism here.

Resources