This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/MSP430FR5994: Solving a System of Linear Simultaneous Equations

Part Number: MSP430FR5994
Other Parts Discussed in Thread: MSP430WARE

Tool/software: Code Composer Studio

Hi,

I need to solve a set of four linear simultaneous equations of the form [A]{x}={b} continuously with new {b} values based on sensor readings. There are a number of methods to solve the equations but I couldn’t find one already coded that I could simply call so I went with Cramer’s method. I am doing as much of the calculation as I can (e.g., calculating |A|, calculating the coefficients required for the other determinants) before the measurement/calculation loop so that I am not repeating steps, but it is still taking too long for the calculation. I am running the MCLK at 16 MHz (as fast as it can go).

How can I do this calculation faster?
- Is there a method already coded that I can simply call? If so, I will still have to determine if it is faster than what I am currently doing.
- Can the DSP be used?
- ?

After the equations are solved I need to do a few other calculations using sqrt, abs and atan2. These are also very slow.  I can sample the sensors very quickly but these calculations are a real bottleneck.

Any help would be appreciated.

Larry

  • Hello Larry - thank you for reaching out with your question on the MSP430FR5994.

    The MSP430FR5994 has both a 32-bit multiplier and LEA (low energy accelerator) that can be leveraged with our MSP DSP library and MSP430Ware IQmath fixed point library to provide quick calculations. Let me check with our DSP software guru to see how to implement the calculations you are asking about.
  • Hi Larry,

    If matrix A is a constant then you can pre-compute the inverse of A and use the matrix multiply functions of the DSPLib to calculate x=A^-1*b. This will be the most efficient approach and utilizes LEA for the matrix multiply. The IQmathLib can then be used to calculate sqrt, abs, atan2 and many other functions based on your algorithm requirements.

    Regards,

    Brent

  • Just the typical approaches used in other applications:

    1. Try to avoid floating point math.
    2. Try to presolve the problem.
    3. Try to use lut.
    4. Try to off load it to a host.
    ...
  • Hi Brent,

    Can you point me to some sample DSP code that will show how to use the DSP functions? I am confused by how to set up the data to use the matrix multiply functions. It seems like I need to use pointers and not just a simple matrix.

    I have been able to use the IQmathLib functions, but the DSP ones are holding me up.

    Thanks,

    Larry
  • Larry,

    The DSP library includes many example projects, the matrix_ex3_mpy_q15 example shows how to allocate three matrices (two source and one result matrix) and then use the matrix multiply API to multiply the two source matrices and store to the result matrix (8x10 * 10x12 = 8x12 result matrix). You should be able to use that as a starting point and modify to match your matrix dimensions.

    Regards,

    Brent

  • Hi Brent,

    Thanks for the info. That's exactly what I was looking for to get started. I compiled/ran the example program "matrix_ex3_mpy_q15.c" with no problems. However, when I try to incorporate the code into my program, the following line in my code

    "status = msp_matrix_mpy_q15(&mpyParams, *DSP_A_Matrix_Inverse, *DSP_B_Vector, *DSP_X_Vector);"

    causes the following error message (note: my program name is LEH_TX.c and the three matrices used are in _q format.)

    >> Compilation failure

    makefile:176: recipe for target 'LEH_TX.out' failed
    gmake: *** [all] Error 2
    makefile:172: recipe for target 'all' failed

    undefined first referenced
    symbol in file
    --------- ----------------
    msp_matrix_mpy_q15 ./main.obj

    This looks like a routine rookie mistake of not setting a path properly, and is usually easy enough to fix, but I can't seem to find it. I am able to define the rows and columns using "mpyParams" without an error. I am using the same path structure in my Include statements in the CCS file properties that the example uses, and I can see the DSP code listed in my project. I even copied all of the DSP code to my project directory, but I can't seem to resolve the error. Like I said, this looks like a rookie mistake.

    Thanks,

    Larry

  • Larry,

    That error is because somehow the DSPLib source code wasn't included or built with the project. Unfortunately it's almost impossible to debug without your project, I know you mentioned you can see the DSPLib source code in your project but can you check that the msp_matrix_mpy_q15.c file is included like in the screenshot below?

    Next you can check that the source code has been built by looking for the .obj file in the Debug folder as shown below.

    If the msp_matrix_mpy_q15.obj file is not in the Debug folder please double check your project settings and maybe try removing the source code and adding it again to your project. You can also try starting with a copy of the DPSLib example and then adding your own source code and project settings on top of it.

    Regards,

    Brent

  • HI Larry,

    I'm going to close this thread since it has been a few days since your last response and I'm assuming you have resolved your issue.
    If this is not the case and you need additional help, you can re-open this same thread.
  • Hi Dennis,

    My apologies for neglecting this, but I have been pulled away on other priorities. For whatever reason I am still unable to link in the DSP functions so I cannot call the routines "msp_matrix_mpy_q15" and "msp_matrix_mpy_iq31". I am sure it is just something silly and I will eventually resolve it once I can get back to it.

    Meanwhile, I have set up my code to solve the system of equations using a number of different methods. First, using Cramer's Rule with 1) floating point, 2) QMath, and 3) iQMath. As expected, floating point is the slowest but most accurate and QMath is the fastest but least accurate. The same comments apply when using the Inverse Matrix Method in place of Cramer's Rule. The Inverse Matrix Method is also slightly faster than Cramer's Rule (at least for my implementation. I have tried to optimize each method by doing as much of the calculations as I can outside the actual solution routine. I am now down to just over 2 ms for the Inverse Matrix method with iQMath and almost 3 ms for Cramer's Rule. I would really like to reduce these times if I can since they are the bottleneck in my data acquisition and processing routines.

    Without seeing my actual code, do you think the DSP functions will be able to improve on that? I don't know how the DSP math routines work. Are they similar to the ones in QMath and iQMath?

    Thanks,

    Larry

  • Larry,

    The DSP functions using LEA will be significantly faster and more efficient than the IQmath functions. A quick estimate says they will be ~30x faster, the Qmath multiply function _QNmpy() takes 47 cycles (link, page 92) while the DSP matrix multiply function msp_matrix_mpy_q15() takes 1.5 cycles per multiply (link, page 22). Similarly the DSP 32-bit matrix multiply will be ~15x faster than the equivalent IQmath function.

    Regards,

    Brent

  • Hello Larry,

    Having installed:
    TI v16.9.6.LTS
    CCS 7.4.0.00015 and
    MSP_EXP430FR5994 rev1.1 which is MSP_LEA_REVISION_A, as I understand,

    I did some tests using the matrix_ex3_mpy_q15.c example to show when we can benefit from LEA (or DSP generally).

    I did A and B matricies multiply with the following sizes and the cycleCount measured values:

    sizes
    A B cycleCount
    4x4 4x1 1,363 !!! 16 mpys and 12 adds
    4x4 4x4 1,464
    8x10 10x12 4,148

    I am a bit surprised.
    And you guys?

    I do not see LEA benefits when multipling matricies by vectors or small matricies.


    Kind regards,

    LEA fun,
    Tomasz
  • Larry,

    I learned a lot about Linear Simultaneous Equations,
    however that was 30 years ago I have never practiced these learnings after studies.

    I would go like this:
    1. having A matrix as a constant I would go to the calculation methods based on a reversed A matrix
    Why? This should eliminate divide operations each time you deal with new {b} readings
    2. having a reversed A matrix I would convert it using Gauss-Jordan method
    Why? The converted matrix should look like this one:
    1 0 0 -140
    0 1 0 49
    0 0 1 -3
    0 0 0 1

    Having Gauss-Jordan matrix you have only three real multiplications.
    Than, using mpy32 should come to the max of possible.

    Numerical stability is always concern.
    Major errors come from substraction operations within deviders.
    Having 10, 12, 16 bits reading for the {b} vector
    and 32 bit math should be possible to avoid pure math errors on a desing.

    One final remark.
    If you do your {b} readings in a control loop having an amplification equel to 1
    and you are approaching phase shift to -180 degrees
    maths precision stars to dominate.
    Tail shakes dog.


    Best regards,
    Tomasz
  • Hi Larry,
    it should be in reply to you:

    In reply to Brent Peterson:
    Hello Larry,

    Having installed:
    TI v16.9.6.LTS
    CCS 7.4.0.00015 and
    MSP_EXP430FR5994 rev1.1 which is MSP_LEA_REVISION_A, as I understand,

    I did some tests using the matrix_ex3_mpy_q15.c example to show when we can benefit from LEA (or DSP generally).

    I did A and B matricies multiply with the following sizes and the cycleCount measured values:

    sizes
    A B cycleCount
    4x4 4x1 1,363 !!! 16 mpys and 12 adds
    4x4 4x4 1,464
    8x10 10x12 4,148

    I am a bit surprised.
    And you guys?

    I do not see LEA benefits when multipling matricies by vectors or small matricies.


    Kind regards,

    LEA fun,
    Tomasz
  • ... and a reply to myself :-)

    In reply to Tomasz Kocon:
    Larry,

    I learned a lot about Linear Simultaneous Equations,
    however that was 30 years ago I have never practiced these learnings after studies.

    I would go like this:
    1. having A matrix as a constant I would go to the calculation methods based on a reversed A matrix
    Why? This should eliminate divide operations each time you deal with new {b} readings
    2. having a reversed A matrix I would convert it using Gauss-Jordan method
    Why? The converted matrix should look like this one:
    1 0 0 -140
    0 1 0 49
    0 0 1 -3
    0 0 0 1

    Having Gauss-Jordan matrix you have only three real multiplications.
    Than, using mpy32 should come to the max of possible.

    Numerical stability is always concern.
    Major errors come from substraction operations within deviders.
    Having 10, 12, 16 bits reading for the {b} vector
    and 32 bit math should be possible to avoid pure math errors on a desing.

    One final remark.
    If you do your {b} readings in a control loop having an amplification equel to 1
    and you are approaching phase shift to -180 degrees
    maths precision stars to dominate.
    Tail shakes dog.


    Best regards,
    Tomasz
  • Tomasz,

    There is some overhead associated with making calls to LEA in addition to the C functions themselves, the advantage of using LEA will increase as the size of the matrices also increases. I ran the following test comparing LEA vs no LEA (by defining MSP_DISABLE_LEA in the compiler settings) using CCS and compiler version v16.9.3.LTS (optimizations set to -O3 and MSP_DISABLE_DIAGNOSTICS defined).

    [4x4] * [4x4] matrix multiply:

    Cycles Cycle per multiply
    LEA 1099 17.171875
    MPY32 2525 39.453125

    [8x10] * [10x20] matrix multiply:

    Cycles Cycle per multiply
    LEA 3547 3.694791667
    MPY32 29049 30.259375

    [24x24] * [24x24] matrix multiply:

    Cycles Cycle per multiply
    LEA 26139 1.890842014
    MPY32 382208 27.64814815

    The first matrix multiply doing 64 multiply and accumulate operations (MAC) is 2.3x faster using LEA, the second matrix multiply is 8.19x faster (960 MAC) and the last matrix multiply is 14.62x faster (13824 MAC). The larger the matrices the closer you get to the "theoretical" cycle counts but even for small data sets there is an advantage to using LEA over the hardware multiplier.

    Regards,

    Brent

  • Brent,

    thank you additional tests and clarification.
    My intention was to reply to Larry and to tell him
    that LEA is not good in case of [4x4] * [4x1] matrix multiply.
    My mistake and I replied to you.

    Having MSP_EXP430FR5994 rev1.1 which is MSP_LEA_REVISION_A,
    out of the box optimisations and NOT defined MSP_DISABLE_DIAGNOSTICS,
    of course using LEA,
    I have obtained the following results:

    [4x4] * [4x1] : 1,363 cycles for 16 MACs
    [4x4] * [4x4] : 1,464 cycles for 64 MACs
    [8x10] * [10x20] : 4,148 cycles for 960 MACs
    [24x24] * [24x24] : 27,685 cycles for 13,824 MACs.

    Comparing first 2 results I estimated 1000+ cycles for overhead.

    Having optimizations set to -O3 and MSP_DISABLE_DIAGNOSTICS defined:
    [24x24] * [24x24] : 25,885 cycles which is 0,97% faster than your result.

    I fully agree with you that the advantage of using LEA will increase as the size of the matrices also increases.

    I just wanted to check how well [4x4] * [4x1] multipy fits to LEA based DSP libs.

    Fanny is that based on your and my tests, and using linear regresion,
    we can well estimate the overhead associated with making calls to LEA.

    For Larry, still I do recommend to invert and convert the [A] matrix using Gauss-Jorgan conversion.


    Regards,

    Tomasz

**Attention** This is a public forum