Close

Matrix inverted, proof of concept in C

A project log for Bike Computer with Flight Software

I want to track my bike rides and get some experience with CoreFlight

jacob-killeleaJacob Killelea 07/31/2019 at 01:593 Comments

I finally got all the steps for a matrix inversion working in C. It hasn't been verified yet and I don't have any new data to work with, but so far things seem promising. In regards to inverting a matrix, which had me stuck for some time, the solution is apparently an LU decomposition and then an inversion:

int signum;
gsl_permutation *permut = gsl_permutation_calloc(DIMS);
gsl_matrix *Scratch  = gsl_matrix_calloc(DIMS, DIMS);
gsl_matrix *Scratch2 = gsl_matrix_calloc(DIMS, DIMS);

gsl_linalg_LU_decomp(Scratch, permut, &signum);
gsl_linalg_LU_invert(Scratch, permut, Scratch2);

Currently, `Scratch` and `Scratch2` are actually statically allocated in order to reduce dynamic memory. Requires a little bit of indirection between `gsl_matrix_view` and `gsl_matrix`, but I prefer it overall.

The new filter output is in green here, overlaid on the sensor data (blue) and the octave version of the filter (red).

Velocity data is still not being used here, which is a big TODO. Without it, the filter is basically just a running average. I still need to collect more data to evaluate, and also integrate this filter into a CoreFlight app.

Discussions

Ken Yap wrote 07/31/2019 at 04:03 point

In the code shown you are dynamically allocating storage for the matrix with the calls to gsl_matrix_calloc(). Scratch and Scratch2 are pointers to the matrix and themselves only take up a couple of pointers worth of space, either local or global. This is probably how the library is intended to be used.

Curious why you want to avoid dynamic storage allocation. If the RPi is running Linux, dynamic allocation in programs is commonplace and unremarkable.

  Are you sure? yes | no

Jacob Killelea wrote 07/31/2019 at 04:16 point

Correct - apologies for the confusion, I wrote callocs here so that it wouldn't just look like dangling pointers.
In the actual code, I have:
```

double Scratch_data[] = {0....};

gsl_matrix_view Scratch_view = gsl_matrix_view_array(Scratch_data);

gsl_matrix *Scratch = &Scratch_view.matrix;

```

It's definitely more roundabout than a calloc, but I'm trying to write "flight-like" software, which prefers a static memory footprint. No real requirements on this other than my own preference.

  Are you sure? yes | no

Ken Yap wrote 07/31/2019 at 04:28 point

Unless Scratch_data has to be initialised to something non-zero, I would leave out the initialisation as that will cause the variable to be put in the DATA section increasing executable size and load time, while leaving it out will put it in the BSS section which will be zeroed on program startup anyway.

  Are you sure? yes | no