当前位置:   article > 正文

【研发日记】Matlab/Simulink软件优化(三)——利用NaNFlag为数据处理算法降阶

【研发日记】Matlab/Simulink软件优化(三)——利用NaNFlag为数据处理算法降阶

文章目录

前言

背景介绍

初始算法

优化算法

分析和应用

总结


前言

        见《【研发日记】Matlab/Simulink软件优化(一)——动态内存负荷压缩

        见《【研发日记】Matlab/Simulink软件优化(二)——通信负载柔性均衡算法

背景介绍

        在一个嵌入式软件开发项目中,需要开发一个数据处理算法,功能是求解一个动态变化数组的平均值、极值和极值位号,并且具备动态剔除个别元素(元素序列不变)的功能。示例如下:

数组:2、4、6、8、10

剔除:第1个元素、第3个元素

求均值:(4 + 8 + 10)/ 3 = 7.3

求最小值:4

求最小值位号:2

求最大值:10

求最大值位号:5

初始算法

        一开始算法开发的思路非常简单,就是根据上述示例把求解过程拆分成两步,第一步构建剔除特定元素后的新数组,第二步分别求解统计结果,示例如下:

        以上模型生成的代码如下:

  1. #include "untitled.h"
  2. #include "untitled_private.h"
  3. /* External outputs (root outports fed by signals with default storage) */
  4. ExtY_untitled_T untitled_Y;
  5. /* Real-time model */
  6. static RT_MODEL_untitled_T untitled_M_;
  7. RT_MODEL_untitled_T *const untitled_M = &untitled_M_;
  8. /* Model step function */
  9. void untitled_step(void)
  10. {
  11. real_T Array_min[5];
  12. real_T ArrayIndex;
  13. int32_T b_idx;
  14. int32_T b_k;
  15. int32_T e_k;
  16. int32_T i;
  17. /* MATLAB Function: '<Root>/MATLAB Function' incorporates:
  18. * Constant: '<Root>/Constant'
  19. */
  20. for (i = 0; i < 5; i++) {
  21. Array_min[i] = untitled_ConstP.Constant_Value[i];
  22. }
  23. Array_min[0] = 255.0;
  24. Array_min[2] = 255.0;
  25. untitled_Y.Out2 = 255.0;
  26. b_idx = 1;
  27. for (b_k = 1; b_k + 1 < 6; b_k++) {
  28. if (untitled_Y.Out2 > Array_min[b_k]) {
  29. untitled_Y.Out2 = Array_min[b_k];
  30. b_idx = b_k + 1;
  31. }
  32. }
  33. for (i = 0; i < 5; i++) {
  34. Array_min[i] = untitled_ConstP.Constant_Value[i];
  35. }
  36. Array_min[0] = 0.0;
  37. Array_min[2] = 0.0;
  38. untitled_Y.Out4 = 0.0;
  39. b_k = 1;
  40. for (i = 1; i + 1 < 6; i++) {
  41. if (untitled_Y.Out4 < Array_min[i]) {
  42. untitled_Y.Out4 = Array_min[i];
  43. b_k = i + 1;
  44. }
  45. }
  46. for (i = 0; i < 5; i++) {
  47. Array_min[i] = 0.0;
  48. }
  49. ArrayIndex = 0.0;
  50. for (i = 0; i < 5; i++) {
  51. if ((i + 1 != 1) && (i + 1 != 3)) {
  52. ArrayIndex++;
  53. Array_min[(int32_T)ArrayIndex - 1] = untitled_ConstP.Constant_Value[i];
  54. }
  55. }
  56. if (1.0 > ArrayIndex) {
  57. i = -1;
  58. } else {
  59. i = (int32_T)ArrayIndex - 1;
  60. }
  61. if ((int8_T)(i + 1) == 0) {
  62. ArrayIndex = 0.0;
  63. } else if ((int8_T)(i + 1) == 0) {
  64. ArrayIndex = 0.0;
  65. } else {
  66. ArrayIndex = Array_min[0];
  67. for (e_k = 2; e_k <= (int8_T)(i + 1); e_k++) {
  68. ArrayIndex += Array_min[e_k - 1];
  69. }
  70. }
  71. /* Outport: '<Root>/Out1' incorporates:
  72. * MATLAB Function: '<Root>/MATLAB Function'
  73. */
  74. untitled_Y.Out1 = ArrayIndex / (real_T)(int8_T)(i + 1);
  75. /* Outport: '<Root>/Out3' incorporates:
  76. * MATLAB Function: '<Root>/MATLAB Function'
  77. */
  78. untitled_Y.Out3 = b_idx;
  79. /* Outport: '<Root>/Out5' incorporates:
  80. * MATLAB Function: '<Root>/MATLAB Function'
  81. */
  82. untitled_Y.Out5 = b_k;
  83. }
  84. /* Model initialize function */
  85. void untitled_initialize(void)
  86. {
  87. /* (no initialization code required) */
  88. }
  89. /* Model terminate function */
  90. void untitled_terminate(void)
  91. {
  92. /* (no terminate code required) */
  93. }

        上述代码仿真运行没有什么问题,从结果来看是符合功能需求的,示例如下:

        分析上述代码会发现构建新数组时存在一些问题。如果数组中出现大于255的值,或者小于0的负数时,算法就需要重新匹配。如果数组的Size大于5,或者剔除的个数大于2,算法也需要重新匹配。这种繁复的工作,是我们不希望看到的。

优化算法

        针对上述问题的分析和研究,发现Matlab官方提供了一个现成的函数功能,可用于剔除特定元素的数据统计算法,能让我们简化构建新数组的工作,也就免去繁复匹配算法的问题,示例如下:

        Tips:因为有NaN的存在,数组的数据类型如果不是double可能会出问题。例如NaN赋给uint8的数组是,对应元素就会变成0,再后续的求解函数中是按0对待的。

        以上模型生成的代码如下:

  1. #include "untitled.h"
  2. #include "untitled_private.h"
  3. /* External outputs (root outports fed by signals with default storage) */
  4. ExtY_untitled_T untitled_Y;
  5. /* Real-time model */
  6. static RT_MODEL_untitled_T untitled_M_;
  7. RT_MODEL_untitled_T *const untitled_M = &untitled_M_;
  8. /* Model step function */
  9. void untitled_step(void)
  10. {
  11. real_T data[5];
  12. real_T y;
  13. int32_T c_k;
  14. int32_T i;
  15. int32_T k;
  16. boolean_T exitg1;
  17. /* MATLAB Function: '<Root>/MATLAB Function' incorporates:
  18. * Constant: '<Root>/Constant'
  19. */
  20. for (i = 0; i < 5; i++) {
  21. data[i] = untitled_ConstP.Constant_Value[i];
  22. }
  23. data[0] = (rtNaN);
  24. data[2] = (rtNaN);
  25. i = 0;
  26. k = 2;
  27. exitg1 = false;
  28. while ((!exitg1) && (k < 6)) {
  29. if (!rtIsNaN(data[k - 1])) {
  30. i = k;
  31. exitg1 = true;
  32. } else {
  33. k++;
  34. }
  35. }
  36. if (i == 0) {
  37. /* Outport: '<Root>/Out2' */
  38. untitled_Y.Out2 = (rtNaN);
  39. i = 1;
  40. } else {
  41. untitled_Y.Out2 = data[i - 1];
  42. for (k = i; k < 5; k++) {
  43. if (untitled_Y.Out2 > data[k]) {
  44. untitled_Y.Out2 = data[k];
  45. i = k + 1;
  46. }
  47. }
  48. }
  49. k = 0;
  50. c_k = 2;
  51. exitg1 = false;
  52. while ((!exitg1) && (c_k < 6)) {
  53. if (!rtIsNaN(data[c_k - 1])) {
  54. k = c_k;
  55. exitg1 = true;
  56. } else {
  57. c_k++;
  58. }
  59. }
  60. if (k == 0) {
  61. /* Outport: '<Root>/Out4' */
  62. untitled_Y.Out4 = (rtNaN);
  63. k = 1;
  64. } else {
  65. untitled_Y.Out4 = data[k - 1];
  66. for (c_k = k; c_k < 5; c_k++) {
  67. if (untitled_Y.Out4 < data[c_k]) {
  68. untitled_Y.Out4 = data[c_k];
  69. k = c_k + 1;
  70. }
  71. }
  72. }
  73. y = 0.0;
  74. c_k = 0;
  75. if (!rtIsNaN(data[1])) {
  76. y = data[1];
  77. c_k = 1;
  78. }
  79. if (!rtIsNaN(data[3])) {
  80. y += data[3];
  81. c_k++;
  82. }
  83. if (!rtIsNaN(data[4])) {
  84. y += data[4];
  85. c_k++;
  86. }
  87. /* Outport: '<Root>/Out1' incorporates:
  88. * MATLAB Function: '<Root>/MATLAB Function'
  89. */
  90. untitled_Y.Out1 = y / (real_T)c_k;
  91. /* Outport: '<Root>/Out3' incorporates:
  92. * MATLAB Function: '<Root>/MATLAB Function'
  93. */
  94. untitled_Y.Out3 = i;
  95. /* Outport: '<Root>/Out5' incorporates:
  96. * MATLAB Function: '<Root>/MATLAB Function'
  97. */
  98. untitled_Y.Out5 = k;
  99. }
  100. /* Model initialize function */
  101. void untitled_initialize(void)
  102. {
  103. /* Registration code */
  104. /* initialize non-finites */
  105. rt_InitInfAndNaN(sizeof(real_T));
  106. }
  107. /* Model terminate function */
  108. void untitled_terminate(void)
  109. {
  110. /* (no terminate code required) */
  111. }

        Tips:从生成的C代码来看,底层逻辑的实现方法与前一种是类似的

        上述代码仿真运行也没有问题,结果符合需求,示例如下:

        分析上述算法的特点,不仅实现了项目中的需求,同时也利用NaNFlag为数据处理算法进行了降阶

分析和应用

        利用NaNFlag开发数据处理算法时,需要注意如下几点:

        1、两种算法生成的代码,底层逻辑都一样,但是是开发复杂度软件成熟度上差别好多,前者更适合用于逻辑探索和思维训练,后者跟适合于工程应用

        2、两种算法的开发自由度不同,可裁剪和压缩负载的空间也不同。前者可以根据实际应用裁剪出自己需要的数组大小,选取自己够用的数据类型,能更极致压缩算法对内存资源算力资源的消耗。后者是把一部分算法设计工作交给代码生成工具去做了,开发者就没有这么大的灵活度了。前者更适用于处理器资源有限的专用嵌入式项目,后者更实用于模块化平台化开发的项目。

总结

        以上就是本人在嵌入式软件开发中设计数据处理算法时,一些个人理解和分析的总结,首先介绍了它的背景情况,然后展示它的初始设计和优化设计,最后分析了利用NaNFlag开发数据处理算法的注意事项和应用场景。

        后续还会分享另外几个最近总结的软件优化知识点,欢迎评论区留言、点赞、收藏和关注,这些鼓励和支持都将成文本人持续分享的动力。

        另外,上述例程使用的Demo工程,可以到笔者的主页查找和下载。


        版权声明:原创文章,转载和引用请注明出处和链接,侵权必究

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/710909
推荐阅读
相关标签
  

闽ICP备14008679号