Skip to content
Snippets Groups Projects
Commit 3b91b75f authored by Andrea Censi's avatar Andrea Censi
Browse files

No commit message

No commit message
parent 91241f4e
No related branches found
No related tags found
No related merge requests found
......@@ -40,6 +40,9 @@ PROJECT (scan_matching_lib C)
ADD_EXECUTABLE(test_egsl lib/egsl/egsl_test.c)
TARGET_LINK_LIBRARIES(test_egsl egsl ${GSL_LIBRARIES})
ADD_EXECUTABLE(egsl_test_allocation lib/egsl/egsl_test_allocation.c)
TARGET_LINK_LIBRARIES(egsl_test_allocation egsl ${GSL_LIBRARIES})
########### SM ##########
ADD_LIBRARY(sm STATIC
......
header=header.html_frag
footer=footer.html_frag
README.html: README.txt $(header) $(footer)
cat $(header) > $@
Markdown.pl $< >> $@
cat $(footer) >> $@
Easy GSL: Making GSL easy for simple tasks.
=======================================
This is a small C library that I wrote for making simple matrix
computations easy. It is based on
[GSL, the GNU Scientific Library](http://www.gnu.org/software/gsl/).
Albeit very powerful, the GSL is definitely not user-friendly for
making simple matrix computations.
Instead, EGSL will try to fool you into thinking that you are using Matlab.
Yes, it's that easy! You can forget all of that `gsl_matrix_alloc`
and `gsl_matrix_free`.
This is not designed for large matrixes.
### Download
Download from [http://purl.org/censi/2006/egsl](http://purl.org/censi/2006/egsl).
The two main features
---------------------
### Feature #1: Automatic (de)allocation of matrixes
Its main feature is that matrixes are automatically allocated and
deallocated. For example, you can write:
egsl_push();
val v1 = zeros(10,10);
val v2 = ones(10,10);
val v3 = sum(v1, v2);
egsl_print("v1+v2=", v3);
egsl_pop();
and not worry about (de)allocalization.
### Feature #2: Caching of matrixes
This feature makes EGSL faster than any other C++ equivalent that
uses objects. Consider this code:
egsl_push();
val v1 = zeros(10,10);
for(int i=0;i<1000000;i++) {
egsl_push();
val v2 = zeros(10,10);
// make some operation on v2
....
// add v2 to v1
add_to(v1, v2);
egsl_pop();
}
egsl_pop();
// Prints statistics about EGSL's usage of memory
egsl_print_stats();
The output of this program is:
egsl: total allocations: 2 cache hits:999999
Even though the loop executes one million times, the total number
of matrix allocations is 2. Note that there is an inner context.
When the loop runs the first time, the `gsl_matrix` for `v2` is allocated.
However, when the `egsl_pop()` is reached, this matrix is not deallocated.
When the loop runs the second time, EGSL detects that you already
allocated a matrix of the requested size and re-utilizes the memory.
Usage
-----
For EGSL to work, you must remember some simple rules:
1. Always include your code between a pair of `egsl_push`/`egsl_pop` calls.
2. All values are returned as `val` structs: `val` object are not valid outside of the context they are created into (unless you tell EGSL).
Useful macros
-------------
Available operations
--------------------
</body></html>
\ No newline at end of file
<html>
<head>
<title>Easy GSL</title>
<style type="text/css">
body * {
max-width: 35em;
}
body {
padding-left: 3cm;
}
h1 { margin-left: -1cm;}
h2 {
margin-left: -1cm; margin-top: +1em;
}
h3 { margin-left: -0.5cm;}
/* Colors */
body { font-family: Georgia, serif;
background-color: white;
color: #333;}
h1, h2 { color: darkblue;}
h3 { color: #333; }
pre {
margin-left: +1em;
padding: +5px;
background-color: #ddd;
color: #0a0;
}
</style>
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
\ No newline at end of file
......@@ -105,10 +105,10 @@ void egsl_pop() {
cid--;
}
void egsl_stats() {
void egsl_print_stats() {
printf("egsl: total allocations: %d cache hits:%d\n",
egsl_total_allocations, egsl_cache_hits);
printf("egsl: sizeof(val) = %d\n",(int)sizeof(val));
// printf("egsl: sizeof(val) = %d\n",(int)sizeof(val));
}
val egsl_alloc(size_t rows, size_t columns) {
......
......@@ -72,7 +72,10 @@ val egsl_rot(double theta);
/// Misc
void egsl_print(const char*str, val);
/// Prints eigenvalues and eigenvectors of a symmetric matrix
void egsl_print_spectrum(const char*s, val v);
void egsl_print_stats();
/// Private implementations things
void egsl_expect_size(val v, size_t rows, size_t cols);
......
......@@ -27,3 +27,19 @@ val egsl_vers(double theta){
double v[2] = { cos(theta), sin(theta)};
return egsl_vFa(2,v);
}
void egsl_print_spectrum(const char*s, val v) {
gsl_matrix *m = egsl_gslm(v);
// expect same size
size_t n = m->size1;
double eval[n]; val evec[n];
egsl_symm_eig(v, eval, evec);
size_t i,j;
for(j=0;j<n;j++) {
printf("%s | eval[%d] = %+5.5f evec[%d]= ",
s, (int)j, eval[j],(int)j);
for(i=0;i<n;i++)
printf("%+4.4f ", egsl_atv(evec[j],i));
printf(" sqrt(eval[%d])=%5.5f \n", (int)j, sqrt(eval[j]));
}
}
\ No newline at end of file
......@@ -5,17 +5,35 @@
int main() {
egsl_push();
val R = rot(M_PI/2);
// Creates a vector from a double array
double p[2] = {1,2};
val vp = egsl_vFa(2,p);
// Creates a matrix from a double array
double md[4] = {
1, 2,
0, -1
};
val m = egsl_vFda(2,2,md);
val vrot = m(R, vp);
// Creates a rotation matrix
val R = rot(M_PI/2);
// Multiplies the three together
val vrot = m3(R, m, vp);
// Displays the results
egsl_print("R", R);
egsl_print("vp", vp);
egsl_print("vrot", vrot);
// Create a semidifinite matrix (symmetric part of R)
val A = sc(0.5, sum(m, tr(m)) );
// Displays spectrum
egsl_print("A",A);
egsl_print_spectrum("A",A);
egsl_pop();
return 0;
......
#include "egsl.h"
#include "egsl_macros.h"
int main() {
egsl_push();
val v1 = zeros(10,10);
int i;
for(i=0;i<1000000;i++) {
egsl_push();
val v2 = zeros(10,10);
add_to(v1, v2);
egsl_pop();
}
egsl_pop();
egsl_print_stats();
}
\ No newline at end of file
......@@ -26,8 +26,6 @@ void compute_covariance_exact(
LDP laser_ref, LDP laser_sens, const gsl_vector*x,
val *cov0_x, val *dx_dy1, val *dx_dy2);
void sm_icp(struct sm_params*params, struct sm_result*res) {
egsl_push();
......@@ -119,36 +117,17 @@ void sm_icp(struct sm_params*params, struct sm_result*res) {
// val cov_x = sc(params->sigma*params->sigma, cov0_x);
double eval[3]; val evec[3];
egsl_symm_eig(cov0_x, eval, evec);
egsl_print("cov0_x", cov0_x);
int j;
for(j=0;j<3;j++) {
printf("sqrt(eval[%d])=%5.5f %4.4f %4.4f %4.4f\n", j, sqrt(eval[j]),
egsl_atv(evec[j],0),
egsl_atv(evec[j],1),
egsl_atv(evec[j],2));
}
egsl_print_spectrum("cov0_x", cov0_x);
val fim = ld_fisher0(laser_ref);
val ifim = inv(fim);
double eval2[3]; val evec2[3];
egsl_symm_eig(ifim, eval2, evec2);
egsl_print("fim", fim);
egsl_print("2*inv(fim)", sc(2,ifim));
for(j=0;j<3;j++) {
printf("sqrt(eval[%d])=%5.5f %4.4f %4.4f %4.4f\n", j, sqrt(eval2[j]),
egsl_atv(evec2[j],0),
egsl_atv(evec2[j],1),
egsl_atv(evec2[j],2));
}
egsl_print_spectrum("ifim", ifim);
}
res->error = best_error;
res->iterations = iterations;
res->nvalid = nvalid;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment