相关运算及实现

本文介绍相关运算及实现。

相关运算在相关检测及数字锁相放大中经常用到,其与卷积运算又有一定的联系,本文简要介绍其基本运算及与卷积运算的联系,并给出实现。

1.定义

这里以长度为N的离散时间序列x(n),y(n)为例,相关运算定义如下:

1)R_{xy}(n)

x(n)保持不动,y(n)相对于x(n)向左移动

R_{xy}(n)=\sum_{m=0}^{N-1}x(m)y(m+n)=\sum_{m=0}^{N-1}x(m-n)y(m)

最后面的式子是等效情况下,y(n)不动,x(n)相对于y(n)向右移动

2)R_{yx}(n)

y(n)保持不动,x(n)相对于y(n)向左移动

R_{yx}(n)=\sum_{m=0}^{N-1}y(m)x(m+n)=\sum_{m=0}^{N-1}y(m-n)x(m)

最后面的式子是等效情况下,x(n)不动,y(n)相对于x(n)向右移动

注意:

1)R_{xy}(n)R_{yx}(n)的定义是不一样的,R_{xy}(n)=R_{yx}(-n)

2)n的取值范围为[-(N-1),N-1]

3)相关运算结果长度为2*N-1(2个序列长度和减1)

对比卷积公式:

z(n)=x(n)\ast y(n)=\sum_{m=0}^{N-1}x(m)y(n-m)=\sum_{m=0}^{N-1}y(m)x(n-m)

注意:

1)n的取值范围为[0,2*N-2]

2)卷积运算结果长度为2*N-1(2个序列长度和减1)

3)后面2个等式成立使用的是卷积交换律

对比卷积公式和相关运算公式,可以知道,无论是R_{xy}(n)还是R_{yx}(n),它们与卷积运算差别仅在运算时x(n)或y(n)是否需要折叠(转换成x(-n)或y(-n))。因此,在做相关运算时可以将输入x(n)或y(n)先折叠,再经过卷积运算即可求出相关运算结果。

这里用Matlab作下验证,在Matlab命令行下输入:

x=[1,2,3];
y=[3,2,1];

z1=xcorr(x,y);
z2=conv(x, flip(y));

其中flip(y)即对y进行折叠(反转序列),得到的结果是z1和z2是相等的。

2.实现

这里基于C语言来实现。参考代码如下:

static void correlate(float *pSrcA, uint32_t srcALen, float *pSrcB, uint32_t srcBLen, float *pDst);


static void correlate(float *pSrcA, uint32_t srcALen, float *pSrcB, uint32_t srcBLen, float *pDst)
{
    float *pIn1 = pSrcA;                       /* inputA pointer */
    float *pIn2 = pSrcB + (srcBLen - 1U);      /* inputB pointer */
    float sum = 0;                             /* Accumulator */
    uint32_t i = 0U;                           /* loop counter */
    uint32_t j = 0U;                           /* loop counter */
    uint32_t inv = 0U;                         /* Reverse order flag */
    uint32_t tot = 0U;                         /* Length */

    if ((pSrcA == NULL) || (srcALen == 0) || (pSrcB == NULL) || (srcBLen == 0) || (pDst == NULL))
    {
        return ;
    }

    /* The algorithm implementation is based on the lengths of the inputs. */
    /* srcB is always made to slide across srcA. */
    /* So srcBLen is always considered as shorter or equal to srcALen */
    /* But CORR(x, y) is reverse of CORR(y, x) */
    /* So, when srcBLen > srcALen, output pointer is made to point to the end of the output buffer */
    /* and a varaible, inv is set to 1 */
    /* If lengths are not equal then zero pad has to be done to  make the two
     * inputs of same length. But to improve the performance, we assume zeroes
     * in the output instead of zero padding either of the the inputs*/
    /* If srcALen > srcBLen, (srcALen - srcBLen) zeroes has to included in the
     * starting of the output buffer */
    /* If srcALen < srcBLen, (srcALen - srcBLen) zeroes has to included in the
     * ending of the output buffer */
    /* Once the zero padding is done the remaining of the output is calcualted
     * using convolution but with the shorter signal time shifted. */

    /* Calculate the length of the remaining sequence */
    tot = ((srcALen + srcBLen) - 2U);

    if (srcALen > srcBLen)
    {
      /* Calculating the number of zeros to be padded to the output */
      j = srcALen - srcBLen;

      /* Initialise the pointer after zero padding */
      pDst += j;
    }
    else if (srcALen < srcBLen)
    {
      /* Initialization to inputB pointer */
      pIn1 = pSrcB;

      /* Initialization to the end of inputA pointer */
      pIn2 = pSrcA + (srcALen - 1U);

      /* Initialisation of the pointer after zero padding */
      pDst = pDst + tot;

      /* Swapping the lengths */
      j = srcALen;
      srcALen = srcBLen;
      srcBLen = j;

      /* Setting the reverse flag */
      inv = 1;
    }

    /* Loop to calculate convolution for output length number of times */
    for (i = 0U; i <= tot; i++)
    {
      /* Initialize sum with zero to carry on MAC operations */
      sum = 0.0f;

      /* Loop to perform MAC operations according to convolution equation */
      for (j = 0U; j <= i; j++)
      {
        /* Check the array limitations */
        if ((((i - j) < srcBLen) && (j < srcALen)))
        {
          /* z[i] += x[i-j] * y[j] */
          sum += pIn1[j] * pIn2[-((int32_t)i - (int32_t)j)];
        }
      }
      /* Store the output in the destination buffer */
      if (inv == 1)
      {
        *pDst-- = sum;
      }
      else
      {
        *pDst++ = sum;
      }
    }
}

main函数:

int main()
{
    float x[] = {1, 2, 3, 4};
    float y[] = {4, 3, 2, 1};
    float z[7] = {0};
    uint32_t i = 0;

    correlate(x, 4, y, 4, z);

    for (i = 0; i < sizeof(z) / sizeof(z[0]); i++)
    {
        printf("%f ", z[i]);
    }

    printf("\r\n");

    return 0;
}

输出结果:

作为对比,在Matlab命令行下输入:

x=[1,2,3,4];
y=[4,3,2,1];
z=xcorr(x,y);

查看结果和用C语言实现的是一致的。

3.应用

通过相关运算,我们得到了相关序列,为了方便后续数据处理,需要对得到的相关序列进行归一化处理,对于2个互相关序列,有如下2种归一化方法:

1)有偏估计

\hat{R_{xy,biased}(m)}=\frac{1}{N}\hat{R_{xy}(m)}

2)无偏估计

\hat{R_{xy,unbiased}(m)}=\frac{1}{N-\left | m \right |}\hat{R_{xy}(m)}

为了查看这2者之间差异,在Matlab命令行下,输入如下命令:

fm=1000;
fs=100000;
N=fs/fm;
k=0:1:1000;
theta=pi/8;
x=sin(2*k*pi/N + theta);%原始信号
xn=awgn(x,20,0);%原始信号加噪声
subplot(5,1,1);
plot(k,x);
title('x');
subplot(5,1,2);
plot(k,xn);
title('xn');
[r,lags]=xcorr(xn,x,500);%未缩放的互相关
subplot(5,1,3);
plot(k,r);
title('corr none');
[rb,lags]=xcorr(xn,x,500,'biased');%互相关的有偏估计
subplot(5,1,4);
plot(k,rb);
title('corr biased');
[rub,lags]=xcorr(xn,x,500,'unbiased');%互相关的无偏估计
subplot(5,1,5);
plot(k,rub);
title('corr unbiased');

输出结果:

由图可知:

1)“未缩放的互相关运算”仅是相关运算计算出的序列,在2个互相关信号重叠(相位差为0)时值最大

2)“互相关的有偏估计”在2个互相关信号重叠(相位差为0)时值最大,且为原始信号幅值的一半

3)“互相关的无偏估计”则有如下特点:

a)与原始信号频率相同

b)输出为cos信号,且起始相位为2个互相关信号相位之差(0)

c)信号幅值为原信号幅值的一半

这其实和相敏检波(PSD)运算效果是一致的(未加LPF)。

总结,本文介绍了相关运算及实现。

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

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

相关文章

OSPF域间路由

注&#xff1a;区域&#xff08;area&#xff09;是以接口进行划分的 描述&#xff1a; R1的g0/0/1接口属于area 0 √ R1属于区域0和区域1 1.设计原则 1、OSPF区域的设计原则&#xff1a; 骨干区域有且只能存在一个 非骨干区域必须和骨干区域相连 多区域时&#…

使用JavaScript日历小部件和DHTMLX Gantt的应用场景(一)

DHTMLX Suite UI 组件库允许您更快地构建跨平台、跨浏览器 Web 和移动应用程序。它包括一组丰富的即用式 HTML5 组件&#xff0c;这些组件可以轻松组合到单个应用程序界面中。 DHTMLX Gantt是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表&#xff0c;可满足项目管理应用…

深入了解MySQL:从基础到特性,全面解读关系数据库管理系统的历史与应用

文章目录 1. MySQL简介1.1 概述1.2 架构与兼容性1.3 开源与社区支持 2. MySQL的历史2.1 创始与初衷2.2 发展历程2.3 在Oracle的持续发展2.4 开源与商业结合 3. MySQL的核心特性4. MySQL在实际应用中的作用4.1 网站建设与内容管理4.2 商业智能与客户关系管理4.3 企业级应用与云集…

新媒体运营-----短视频运营-----PR视频剪辑----抠像及美颜磨皮

新媒体运营-----短视频运营-----PR视频剪辑-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/138079659 文章目录 1. 超级键抠像绿(蓝)幕背景2. 常规视频抠像3. 美颜磨皮 1. 超级键抠像绿(蓝)幕背景 如果我们的素材是在摄影棚进行…

【R语言实战】——kNN和朴素贝叶斯方法实战

&#x1f349;CSDN小墨&晓末:https://blog.csdn.net/jd1813346972 个人介绍: 研一&#xff5c;统计学&#xff5c;干货分享          擅长Python、Matlab、R等主流编程软件          累计十余项国家级比赛奖项&#xff0c;参与研究经费10w、40w级横向 文…

.net8系列-04图文并茂手把手教你配置Swagger支持token以及实现Swagger扩展,Swagger代码单独抽离

前情提要 接上篇文章&#xff0c;我们当前已完成如下内容&#xff1a; 创建应用成功创建接口成功配置Swagger实现接口注释和版本控制 本文章主要内容为&#xff1a;配置Swagger支持token传值测试接口 快速上手-代码配置 添加如下代码 文件目录&#xff1a;\xiaojinWebAppl…

06_Scala流程控制

文章目录 [toc] 1.流程控制**小结&#xff1a;** **2. Scala中流程控制没有三元运算符****2.1 Scala中如果逻辑代码只有一行可以省略花括号****小结&#xff1a;** **3. 循环控制****3.1 for控制****3.2循环守卫 --> 循环表达式添加逻辑判断****3.3 循环步长 --> 表示循环…

​「Python大数据」词频数据渲染词云图导出HTML

前言 本文主要介绍通过python实现数据聚类、脚本开发、办公自动化。词频数据渲染词云图导出HTML。 一、业务逻辑 读取voc数据采集的数据批处理,使用jieba进行分词,去除停用词词频数据渲染词云图将可视化结果保存到HTML文件中二、具体产出 三、执行脚本 python wordCloud.p…

Flutter - 折叠面板

demo 地址: https://github.com/iotjin/jh_flutter_demo 代码不定时更新&#xff0c;请前往github查看最新代码 flutter 自定义折叠组件 支持三种类型和两种展示效果可自定义title和被折叠的内容 效果图 示例 import package:flutter/material.dart; import /jh_common/widge…

Faust勒索病毒:了解变种faust,以及如何保护您的数据

导言&#xff1a; 近年来&#xff0c;网络安全问题日益严峻&#xff0c;其中勒索病毒成为了一种日益猖獗的威胁。在众多勒索病毒中&#xff0c;.faust勒索病毒以其高度的隐秘性和破坏性引起了广泛关注。本文91数据恢复将深入剖析.faust勒索病毒的威胁特点&#xff0c;并提出相…

#ESP32S3N8R8(按键点灯)

一、按键对应端口为GPIO0&#xff08;上拉&#xff09; 二、代码 #include <stdio.h> #include "driver/gpio.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "unistd.h"void app_main(void) {int co…

JavaSE字节缓冲流

欢迎来到 请回答1024 的博客 &#x1f353;&#x1f353;&#x1f353;欢迎来到 请回答1024的博客 关于博主&#xff1a; 我是 请回答1024&#xff0c;一个追求数学与计算的边界、时间与空间的平衡&#xff0c;0与1的延伸的后端开发者。 博客特色&#xff1a; 在我的博客中&a…

ElasticSearch 安装(docker)

下载安装包 阿里云链接&#xff1a; elasticSearch.exe https://www.alipan.com/s/3A356NnmWaJ 提取码: 93da 点击链接保存&#xff0c;或者复制本段内容&#xff0c;打开「阿里云盘」APP &#xff0c;无需下载极速在线查看&#xff0c;视频原画倍速播放。 安装步骤 1、首先…

【介绍下OneFlow概念清单】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

INA226模块驱动代码-STM32F103

模块&#xff1a; 平台:STM32F103C8T6 标准库 软件模拟IIC C文件&#xff1a; #include "ina226.h"//delay static void delay_nns(uint16_t D) //30纳秒ns 根据手册要用到IIC的HS高速模式 {while(--D); }void delay_nms(uint16_t ms) //毫秒 {uint16_t i;uint3…

Android Dalvik虚拟机JNI方法的注册过程分析

Dalvik虚拟机在调用一个成员函数的时候&#xff0c;如果发现该成员函数是一个JNI方法&#xff0c;那么就会直接跳到它的地址去执行。也就是说&#xff0c;JNI方法是直接在本地操作系统上执行的&#xff0c;而不是由Dalvik虚拟机解释器执行。由此也可看出&#xff0c;JNI方法是A…

欧科云链:为什么减半对比特币生态的影响正在逐步“减弱”?

出品&#xff5c;OKG Research 作者&#xff5c;Jason Jiang 欧科云链OKLink数据显示&#xff0c;比特币于区块高度840000&#xff08;北京时间2024年4月20日8:09&#xff09;成功完成第四次减半&#xff0c;比特币挖矿奖励正式由6.25BTC减少至3.125BTC。此次减半之后&#x…

微信小程序:11.本地生活小程序制作

开发工具&#xff1a; 微信开发者工具apifox进行创先Mock 项目初始化 新建小程序项目输入ID选择不使用云开发&#xff0c;js传统模版在project.private.config中setting配置项中配置checkinalidKey&#xff1a;false 梳理项目结构 因为该项目有三个tabbar所以我们要创建三…

Mysql_数据库事务

文章目录 &#x1f60a; 作者&#xff1a;Lion J &#x1f496; 主页&#xff1a; https://blog.csdn.net/weixin_69252724 &#x1f389; 主题&#xff1a; MySQL__事务&#xff09; ⏱️ 创作时间&#xff1a;2024年04月26日 ———————————————— 这里写目…

STM32、GD32驱动SHT30温湿度传感器源码分享

一、SHT30介绍 1、简介 SHT30是一种数字湿度和温度传感器&#xff0c;由Sensirion公司生产。它是基于物理蒸发原理的湿度传感器&#xff0c;具有高精度和长期稳定性。SHT30采用I2C数字接口&#xff0c;可以直接与微控制器或其他设备连接。该传感器具有低功耗和快速响应的特点…