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

文章目录

前言

背景介绍

初始算法

优化算法

分析和应用

总结


前言

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

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

背景介绍

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

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

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

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

求最小值:4

求最小值位号:2

求最大值:10

求最大值位号:5

初始算法

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

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

#include "untitled.h"
#include "untitled_private.h"

/* External outputs (root outports fed by signals with default storage) */
ExtY_untitled_T untitled_Y;

/* Real-time model */
static RT_MODEL_untitled_T untitled_M_;
RT_MODEL_untitled_T *const untitled_M = &untitled_M_;

/* Model step function */
void untitled_step(void)
{
  real_T Array_min[5];
  real_T ArrayIndex;
  int32_T b_idx;
  int32_T b_k;
  int32_T e_k;
  int32_T i;

  /* MATLAB Function: '<Root>/MATLAB Function' incorporates:
   *  Constant: '<Root>/Constant'
   */
  for (i = 0; i < 5; i++) {
    Array_min[i] = untitled_ConstP.Constant_Value[i];
  }

  Array_min[0] = 255.0;
  Array_min[2] = 255.0;
  untitled_Y.Out2 = 255.0;
  b_idx = 1;
  for (b_k = 1; b_k + 1 < 6; b_k++) {
    if (untitled_Y.Out2 > Array_min[b_k]) {
      untitled_Y.Out2 = Array_min[b_k];
      b_idx = b_k + 1;
    }
  }

  for (i = 0; i < 5; i++) {
    Array_min[i] = untitled_ConstP.Constant_Value[i];
  }

  Array_min[0] = 0.0;
  Array_min[2] = 0.0;
  untitled_Y.Out4 = 0.0;
  b_k = 1;
  for (i = 1; i + 1 < 6; i++) {
    if (untitled_Y.Out4 < Array_min[i]) {
      untitled_Y.Out4 = Array_min[i];
      b_k = i + 1;
    }
  }

  for (i = 0; i < 5; i++) {
    Array_min[i] = 0.0;
  }

  ArrayIndex = 0.0;
  for (i = 0; i < 5; i++) {
    if ((i + 1 != 1) && (i + 1 != 3)) {
      ArrayIndex++;
      Array_min[(int32_T)ArrayIndex - 1] = untitled_ConstP.Constant_Value[i];
    }
  }

  if (1.0 > ArrayIndex) {
    i = -1;
  } else {
    i = (int32_T)ArrayIndex - 1;
  }

  if ((int8_T)(i + 1) == 0) {
    ArrayIndex = 0.0;
  } else if ((int8_T)(i + 1) == 0) {
    ArrayIndex = 0.0;
  } else {
    ArrayIndex = Array_min[0];
    for (e_k = 2; e_k <= (int8_T)(i + 1); e_k++) {
      ArrayIndex += Array_min[e_k - 1];
    }
  }

  /* Outport: '<Root>/Out1' incorporates:
   *  MATLAB Function: '<Root>/MATLAB Function'
   */
  untitled_Y.Out1 = ArrayIndex / (real_T)(int8_T)(i + 1);

  /* Outport: '<Root>/Out3' incorporates:
   *  MATLAB Function: '<Root>/MATLAB Function'
   */
  untitled_Y.Out3 = b_idx;

  /* Outport: '<Root>/Out5' incorporates:
   *  MATLAB Function: '<Root>/MATLAB Function'
   */
  untitled_Y.Out5 = b_k;
}

/* Model initialize function */
void untitled_initialize(void)
{
  /* (no initialization code required) */
}

/* Model terminate function */
void untitled_terminate(void)
{
  /* (no terminate code required) */
}

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

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

优化算法

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

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

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

#include "untitled.h"
#include "untitled_private.h"

/* External outputs (root outports fed by signals with default storage) */
ExtY_untitled_T untitled_Y;

/* Real-time model */
static RT_MODEL_untitled_T untitled_M_;
RT_MODEL_untitled_T *const untitled_M = &untitled_M_;

/* Model step function */
void untitled_step(void)
{
  real_T data[5];
  real_T y;
  int32_T c_k;
  int32_T i;
  int32_T k;
  boolean_T exitg1;

  /* MATLAB Function: '<Root>/MATLAB Function' incorporates:
   *  Constant: '<Root>/Constant'
   */
  for (i = 0; i < 5; i++) {
    data[i] = untitled_ConstP.Constant_Value[i];
  }

  data[0] = (rtNaN);
  data[2] = (rtNaN);
  i = 0;
  k = 2;
  exitg1 = false;
  while ((!exitg1) && (k < 6)) {
    if (!rtIsNaN(data[k - 1])) {
      i = k;
      exitg1 = true;
    } else {
      k++;
    }
  }

  if (i == 0) {
    /* Outport: '<Root>/Out2' */
    untitled_Y.Out2 = (rtNaN);
    i = 1;
  } else {
    untitled_Y.Out2 = data[i - 1];
    for (k = i; k < 5; k++) {
      if (untitled_Y.Out2 > data[k]) {
        untitled_Y.Out2 = data[k];
        i = k + 1;
      }
    }
  }

  k = 0;
  c_k = 2;
  exitg1 = false;
  while ((!exitg1) && (c_k < 6)) {
    if (!rtIsNaN(data[c_k - 1])) {
      k = c_k;
      exitg1 = true;
    } else {
      c_k++;
    }
  }

  if (k == 0) {
    /* Outport: '<Root>/Out4' */
    untitled_Y.Out4 = (rtNaN);
    k = 1;
  } else {
    untitled_Y.Out4 = data[k - 1];
    for (c_k = k; c_k < 5; c_k++) {
      if (untitled_Y.Out4 < data[c_k]) {
        untitled_Y.Out4 = data[c_k];
        k = c_k + 1;
      }
    }
  }

  y = 0.0;
  c_k = 0;
  if (!rtIsNaN(data[1])) {
    y = data[1];
    c_k = 1;
  }

  if (!rtIsNaN(data[3])) {
    y += data[3];
    c_k++;
  }

  if (!rtIsNaN(data[4])) {
    y += data[4];
    c_k++;
  }

  /* Outport: '<Root>/Out1' incorporates:
   *  MATLAB Function: '<Root>/MATLAB Function'
   */
  untitled_Y.Out1 = y / (real_T)c_k;

  /* Outport: '<Root>/Out3' incorporates:
   *  MATLAB Function: '<Root>/MATLAB Function'
   */
  untitled_Y.Out3 = i;

  /* Outport: '<Root>/Out5' incorporates:
   *  MATLAB Function: '<Root>/MATLAB Function'
   */
  untitled_Y.Out5 = k;
}

/* Model initialize function */
void untitled_initialize(void)
{
  /* Registration code */

  /* initialize non-finites */
  rt_InitInfAndNaN(sizeof(real_T));
}

/* Model terminate function */
void untitled_terminate(void)
{
  /* (no terminate code required) */
}

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

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

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

分析和应用

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

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

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

总结

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

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

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


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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/696763.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

FedAvg论文

论文&#xff1a;Communication-Efficient Learning of Deep Networks from Decentralized Data 原code Reproducing 通过阅读帖子进行的了解。 联邦平均算法就是最典型的平均算法之一。将每个客户端上的本地随机梯度下降和执行模型的平均服务器结合在一起。 联邦优化问题 数…

开发小Tips:切换淘宝,腾讯,官方,yarn,cnpm镜像源,nrm包管理工具的具体使用方式(方便切换镜像源)

由于开发中经常要下载一些软件或者依赖&#xff0c;且大多数的官方源的服务器都在国外&#xff0c;网速比较慢&#xff0c;国内为了方便&#xff0c;国内一些大厂就建立一些镜像&#xff0c;加快下载速度。 1.各大镜像源的切换&#xff1a; 切换淘宝镜像源&#xff1a; npm …

Bio-Info每日一题:Rosalind-06-Counting Point Mutations

&#x1f389; 进入生物信息学的世界&#xff0c;与Rosalind一起探索吧&#xff01;&#x1f9ec; Rosalind是一个在线平台&#xff0c;专为学习和实践生物信息学而设计。该平台提供了一系列循序渐进的编程挑战&#xff0c;帮助用户从基础到高级掌握生物信息学知识。无论你是初…

数据结构笔记 线性表的查找 顺序,折半,分块查找

顺序查找&#xff1a;从头找到尾&#xff0c;或者从尾找到头 顺序查找的性能&#xff1a; 其中&#xff0c;辅助空间的O&#xff08;1&#xff09;用于存放哨兵的 折半查找&#xff1a;向下取整&#xff1a;指当计算的结果不为整数时取小于计算结果的整数。 折半查找的性能&am…

类和对象的学习总结(一)

面向对象和面向过程编程初步认识 C语言是面向过程的&#xff0c;关注过程&#xff08;分析求解问题的步骤&#xff09; 例如&#xff1a;外卖&#xff0c;关注点菜&#xff0c;接单&#xff0c;送单等 C是面向对象的&#xff0c;关注对象&#xff0c;把一件事拆分成不同的对象&…

十大排序

本文将以「 通俗易懂」的方式来描述排序的基本实现。 &#x1f9d1;‍&#x1f4bb;阅读本文前&#xff0c;需要一点点编程基础和一点点数据结构知识 本文的所有代码以cpp实现 文章目录 排序的定义 插入排序 ⭐ &#x1f9d0;算法描述 &#x1f496;具体实现 &#x1f…

记一次Linux下Docker镜像服务器磁盘空间清理

我们开发环境Jenkins构建项目时报服务器磁盘空间不足&#xff0c;导致项目自动化构建部署失败&#xff0c; Docker镜像服务器磁盘空间清理我们做了多次了&#xff0c;之前在清理Docker镜像服务器时走了不少弯路&#xff0c;查了不少Docker镜像服务器空间清理&#xff0c;都大同…

架构设计-全局异常处理器404、405的问题

java web 项目中经常会遇到异常处理的问题&#xff0c;普遍的做法是使用全局异常处理&#xff0c;这样做有以下几种原因&#xff1a; 集中化处理&#xff1a;全局异常处理允许你在一个集中的地方处理整个应用程序中的异常。这有助于减少代码重复&#xff0c;因为你不必在每个可…

C++的string类

目录 一、导入 二、接口学习 1.默认成员函数 2.迭代器相关的函数iterator 3.与容量相关的函数Capacity系列 4.与成员权限相关的函数Element access: 5.修改器相关的函数Modifiers&#xff1a; 6.字符串操作接口函数String operations:​编辑 三、扩展 一、导入 学习过…

修复损坏的Excel文件比你想象的要简单,这里提供几种常见的修复方法

打开重要的Excel文件时遇到问题吗?Microsoft Excel是否要求你验证文件是否已损坏?Excel文件可能由于各种原因而损坏,从而无法打开。但不要失去希望;你可以轻松修复损坏的Excel文件。 更改Excel信任中心设置 Microsoft Excel有一个内置的安全功能,可以在受限模式下打开有…

阿里通义千问 Qwen2 大模型开源发布

阿里通义千问 Qwen2 大模型开源发布 Qwen2 系列模型是 Qwen1.5 系列模型的重大升级。该系列包括了五个不同尺寸的预训练和指令微调模型&#xff1a;Qwen2-0.5B、Qwen2-1.5B、Qwen2-7B、Qwen2-57B-A14B 以及 Qwen2-72B。 在中文和英文的基础上&#xff0c;Qwen2 系列的训练数…

前端开发部署:Visual Studio Code + vue

〇 说明 本教程全部采用默认安装路径&#xff0c;因为在进行自定义路径安装的时候&#xff0c;需要配置各种环境变量&#xff0c;在这个配置过程中&#xff0c;可能出现各种很混乱的问题。 一 安装Node.js 1 下载https://nodejs.org/en 2 按照默认NEXT执行 C:\Program Files…

C++ BFS相关题目

目录 图像渲染 岛屿数量 图像渲染 733. 图像渲染 vis就是标记1有没有被用过 符合条件的都放到队列里&#xff0c;每次出队列一个&#xff0c;判四个&#xff0c; 如果要改的值与当前的值相同直接返回 注意&#xff1a;image[x][y] prev要放在坐标判断的后面&#xff…

深度解析地铁票务系统的技术架构与创新应用

在城市交通体系中&#xff0c;地铁作为一种快速、便捷的公共交通方式&#xff0c;已经成为现代都市生活的重要组成部分。而地铁票务系统的技术架构&#xff0c;则是支撑地铁运营的核心之一。本文将深度解析地铁票务系统的技术架构与创新应用&#xff0c;从系统设计、数据管理、…

PE文件(七)扩大节合并节数据目录

添加shellcode有以下几种的方式&#xff1a; 1.直接在任意节的空白区添加代码 2.新增节添加代码 3.扩大最后一个节添加代码 4.合并节并添加代码 今天我们学习如何扩大节&#xff0c;合并节 扩大节 在上一节的学习中&#xff0c;我们可以通过上移NT头和节表覆盖DOS Stub以…

前端技术回顾系列 08|TS 泛型基础

在微信中阅读,关注公众号:CodeFit。 创作不易,如果你觉得这篇文章对你有帮助,请不要忘了 点赞、分享 和 关注 我的公众号:CodeFit,为我的持续创作提供一些动力。 上篇内容回顾:枚举(Enums) 在上篇文章中,我们详细回顾了 TypeScript 中的 枚举(Enums)。 枚举 是一…

spark第三篇sql

spark第三篇sql sparksql概述sparksql四大特性dataframe概述通过读取数据源创建dataFrameDataFrame常用操作DataSet将RDD转换为DataFrame代码开发sparksql 操作hivesqlsparksql读取mysql表中的数据sparksql将结果数据写入到mysql中 sparksql概述 1、sparksql发展史 shark为spa…

HTML静态网页成品作业(HTML+CSS)—— 环保主题介绍网页(5个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有5个页面。 二、作品演示 三、代…

MQ解决的问题

系统中MQ能解决哪些问题&#xff1f; 1.不同语言的程序使用MQ通信 2.分布式&#xff0c;微服务&#xff0c;之间的通信&#xff0c;实现服务质检解耦 3.高并发实现销峰作用 4.实现异步&#xff0c;提高用户体验。

“程序员职业素养全解析:技能、态度与价值观的融合“

文章目录 每日一句正能量前言专业精神专业精神的重要性技术执着追求的故事结论 沟通能力沟通能力的重要性团队合作意识实际工作中的沟通案例结论 持续学习持续学习的重要性学习方法进步经验结论 后记 每日一句正能量 梦不是为想象&#xff0c;而是让我们继续前往。 前言 在数字…