将 matlab 脚本转换为 C 程序的移动平均线
Movin Average conveting matlab script to C program
我正在尝试用 C 编写移动平均线代码,我已经在 matlab 中完成了并且可以运行。我已经手动将matlab脚本转换为C语言,但我遇到了一些问题。
#include <stdio.h>
#include <stdlib.h>
int main()
{
int m = 16; // MEDIA LENGTH
double x[]=0; // X VECTOR = 0
double coef[]=0; // COEF VECTOR = 0
double i; // FOR COUNT VARIABLE
double n; // FOR COUNT VARIABLE
double itera; // LENGTH OF THE INPUT FILE
double aux; // AUX VARIABLE TO MAKE THE SUM
double y[]=0; // AUX VECTOR TO RECEIVE X VECTOR
double saida[]=0; // OUTPUT VECTOR
FILE *arq; // POINTER TO THE FILE
for (i = 0; i < m; i++) {
coef[i] = 1/m;
}
arq = fopen("sweep_100_3400.pcm", "rb");
if (arq == NULL)
{
printf("ERROR WHILE OPENING THE FILE\n");
return;
}
fread(*x,sizeof(double),m,arq);
fclose(arq);
itera = size_t(x);
for (i=0; i < itera; i++) {
y[0] = x[i];
aux=0;
for (n=0; n<m; n++){
aux= aux + coef[n] * y[n];
}
saida[i]=aux;
for (n=m; n <2; n--){
x[n] = x[n-1];
}
}
arq=fopen("saida_medial_movel_c.pcm","wb");
fwrite(*saida, sizeof(double),itera,arq);
fclose(arq);
}
我的编译器在变量声明中显示错误:
error: invalid initializer
当我尝试使用 fread 和 fopen 时出现错误:
error: incompatible type for argument 1 of 'fread'
有人知道这是什么吗?
matlab中的脚本如下:
%MOVING AVERAGE EXAMPLE SCRIPT
clear all;
close all;
clc;
% DEFINES MEDIA LENGTH
m = 16;
%VECTOS EQUAL ZERO
x = zeros (m,1);
coef = zeros (m,1);
%INITIALIZE VECTOR
for j = 1 : m,
coef (j,1) = 1/m;
end
%READ INPUT FILE
fid = fopen ('sweep_100_3400.pcm','rb');
s = fread (fid, 'int16');
fclose(fid);
subplot(2,1,1);
plot(s);
grid on;
title('ENTRADA DO FILTRO');
%PROCESS
itera = length(s);
sav_y = zeros (itera, 1);
%EXECUTE PROCESS
for j = 1 : itera,
x(1,1) = s (j,1);
%PRODUCTS SUM
y=0;
for n = 1 : m,
y = y + coef(n,1) * x(n,1);
end
sav_y(j,1) = y;
%SHIFT THE VECTOR
for n = m: -1 : 2,
x (n,1) = x(n-1,1);
end
end
%PLOT OUTPUT
subplot (2,1,2);
plot (sav_y);
grid on;
title('SAÍDA DO FLITRO');
%SAVE THE OUTPUT IN ANOTHER FILE
fid = fopen('saida_mm_manual.pcm','wb');
fwrite(fid,sav_y,'int16');
fclose(fid);
更新:使用下面的答案和绝对路径来读写de文件。
路径为:arq = fopen("D:\Estudo\Univaliº semestre\DSP\MediMovelC\MediaMovel\sweep_100_3400.pcm", "rb");
CodeBlocks 给我以下错误:
warning: unknown escape sequence: '\D'
warning: unknown escape sequence: '\s'
路径图片:
我已经修复了你的源代码,所以它可以编译。
我花了几分钟才修好,你辛苦了。将 matlab 转换为 C 时的主要错误:
- 数组的工作方式不同。您不能调整 array/define 的大小,它为空然后追加(好吧,您可以,但这需要重新分配,当您已经知道大小时更好)
- 循环索引必须使用整数
- 你失去了指针的用法:)
如果 m 是大于 1 的整数,1/m
为零。要获得双精度值,只需输入 1.0/m
- 输入文件是一个短整数列表
这是差异,评论:
5a6
> #define m 16 // MEDIA LENGTH (had to put a macro to be able to define an array
9,14c10,14
< int m = 16; // MEDIA LENGTH
< double x[]=0; // X VECTOR = 0
< double coef[]=0; // COEF VECTOR = 0
< double i; // FOR COUNT VARIABLE
< double n; // FOR COUNT VARIABLE
< double itera; // LENGTH OF THE INPUT FILE
---
> short *x; // X VECTOR = 0 cannot define a resizeable array like in matlab
> double coef[m]; // COEF VECTOR = 0
> int i; // FOR COUNT VARIABLE indices must be integers
> int n; // FOR COUNT VARIABLE
> int itera; // LENGTH OF THE INPUT FILE
16,17c16,17
< double y[]=0; // AUX VECTOR TO RECEIVE X VECTOR
< double saida[]=0; // OUTPUT VECTOR
---
> double *y; // AUX VECTOR TO RECEIVE X VECTOR
> double *saida; // OUTPUT VECTOR
21c21
< coef[i] = 1/m;
---
> coef[i] = 1.0/m;
29c29
... this zone has heavy edits because it was completely wrong
>
36c41
< aux= aux + coef[n] * y[n];
---
> aux += coef[n] * y[n]; // more C-like
44c49
< fwrite(*saida, sizeof(double),itera,arq);
---
> fwrite(saida, sizeof(double),itera,arq); // already a pointer
45a51,53
> free(saida); // free memory
> free(y);
> free(x);
这是固定代码。请注意,我不确定它是否有效,但它可以编译。如果出现问题,请使用调试器
#include <stdio.h>
#include <stdlib.h>
#define m 16 // MEDIA LENGTH
int main()
{
short *x; // X VECTOR = 0
double coef[m]; // COEF VECTOR = 0
int i; // FOR COUNT VARIABLE
int n; // FOR COUNT VARIABLE
int itera; // LENGTH OF THE INPUT FILE
double aux; // AUX VARIABLE TO MAKE THE SUM
double *y; // AUX VECTOR TO RECEIVE X VECTOR
double *saida; // OUTPUT VECTOR
FILE *arq; // POINTER TO THE FILE
for (i = 0; i < m; i++) {
coef[i] = 1.0/m;
}
arq = fopen("sweep_100_3400.pcm", "rb");
if (arq == NULL)
{
printf("ERROR WHILE OPENING THE FILE\n");
return;
}
// compute size of file
fseek(arq,0,SEEK_END);
itera = ftell(arq)/sizeof(short);
rewind(arq);
// alloc mem for x, read the vector from input file
x = malloc(itera*sizeof(short));
fread(x,sizeof(short),itera,arq);
fclose(arq);
// alloc mem for y
y = malloc(itera*sizeof(double));
saida = malloc(itera*sizeof(double));
for (i=0; i < itera; i++) {
y[0] = x[i];
aux=0;
for (n=0; n<m; n++){
aux += coef[n] * y[n];
}
saida[i]=aux;
for (n=m; n <2; n--){
x[n] = x[n-1];
}
}
arq=fopen("saida_medial_movel_c.pcm","wb");
fwrite(saida, sizeof(double),itera,arq);
fclose(arq);
free(saida);
free(y);
free(x);
}
我的建议是宁愿使用 C++,因为有了 std::vector
和 std::string
,您可以更快地移植东西,并且崩溃、内存泄漏和未定义行为的风险更小。嗯,也许下次...
我正在尝试用 C 编写移动平均线代码,我已经在 matlab 中完成了并且可以运行。我已经手动将matlab脚本转换为C语言,但我遇到了一些问题。
#include <stdio.h>
#include <stdlib.h>
int main()
{
int m = 16; // MEDIA LENGTH
double x[]=0; // X VECTOR = 0
double coef[]=0; // COEF VECTOR = 0
double i; // FOR COUNT VARIABLE
double n; // FOR COUNT VARIABLE
double itera; // LENGTH OF THE INPUT FILE
double aux; // AUX VARIABLE TO MAKE THE SUM
double y[]=0; // AUX VECTOR TO RECEIVE X VECTOR
double saida[]=0; // OUTPUT VECTOR
FILE *arq; // POINTER TO THE FILE
for (i = 0; i < m; i++) {
coef[i] = 1/m;
}
arq = fopen("sweep_100_3400.pcm", "rb");
if (arq == NULL)
{
printf("ERROR WHILE OPENING THE FILE\n");
return;
}
fread(*x,sizeof(double),m,arq);
fclose(arq);
itera = size_t(x);
for (i=0; i < itera; i++) {
y[0] = x[i];
aux=0;
for (n=0; n<m; n++){
aux= aux + coef[n] * y[n];
}
saida[i]=aux;
for (n=m; n <2; n--){
x[n] = x[n-1];
}
}
arq=fopen("saida_medial_movel_c.pcm","wb");
fwrite(*saida, sizeof(double),itera,arq);
fclose(arq);
}
我的编译器在变量声明中显示错误:
error: invalid initializer
当我尝试使用 fread 和 fopen 时出现错误:
error: incompatible type for argument 1 of 'fread'
有人知道这是什么吗?
matlab中的脚本如下:
%MOVING AVERAGE EXAMPLE SCRIPT
clear all;
close all;
clc;
% DEFINES MEDIA LENGTH
m = 16;
%VECTOS EQUAL ZERO
x = zeros (m,1);
coef = zeros (m,1);
%INITIALIZE VECTOR
for j = 1 : m,
coef (j,1) = 1/m;
end
%READ INPUT FILE
fid = fopen ('sweep_100_3400.pcm','rb');
s = fread (fid, 'int16');
fclose(fid);
subplot(2,1,1);
plot(s);
grid on;
title('ENTRADA DO FILTRO');
%PROCESS
itera = length(s);
sav_y = zeros (itera, 1);
%EXECUTE PROCESS
for j = 1 : itera,
x(1,1) = s (j,1);
%PRODUCTS SUM
y=0;
for n = 1 : m,
y = y + coef(n,1) * x(n,1);
end
sav_y(j,1) = y;
%SHIFT THE VECTOR
for n = m: -1 : 2,
x (n,1) = x(n-1,1);
end
end
%PLOT OUTPUT
subplot (2,1,2);
plot (sav_y);
grid on;
title('SAÍDA DO FLITRO');
%SAVE THE OUTPUT IN ANOTHER FILE
fid = fopen('saida_mm_manual.pcm','wb');
fwrite(fid,sav_y,'int16');
fclose(fid);
更新:使用下面的答案和绝对路径来读写de文件。
路径为:arq = fopen("D:\Estudo\Univaliº semestre\DSP\MediMovelC\MediaMovel\sweep_100_3400.pcm", "rb");
CodeBlocks 给我以下错误:
warning: unknown escape sequence: '\D'
warning: unknown escape sequence: '\s'
路径图片:
我已经修复了你的源代码,所以它可以编译。
我花了几分钟才修好,你辛苦了。将 matlab 转换为 C 时的主要错误:
- 数组的工作方式不同。您不能调整 array/define 的大小,它为空然后追加(好吧,您可以,但这需要重新分配,当您已经知道大小时更好)
- 循环索引必须使用整数
- 你失去了指针的用法:) 如果 m 是大于 1 的整数,
1/m
为零。要获得双精度值,只需输入1.0/m
- 输入文件是一个短整数列表
这是差异,评论:
5a6
> #define m 16 // MEDIA LENGTH (had to put a macro to be able to define an array
9,14c10,14
< int m = 16; // MEDIA LENGTH
< double x[]=0; // X VECTOR = 0
< double coef[]=0; // COEF VECTOR = 0
< double i; // FOR COUNT VARIABLE
< double n; // FOR COUNT VARIABLE
< double itera; // LENGTH OF THE INPUT FILE
---
> short *x; // X VECTOR = 0 cannot define a resizeable array like in matlab
> double coef[m]; // COEF VECTOR = 0
> int i; // FOR COUNT VARIABLE indices must be integers
> int n; // FOR COUNT VARIABLE
> int itera; // LENGTH OF THE INPUT FILE
16,17c16,17
< double y[]=0; // AUX VECTOR TO RECEIVE X VECTOR
< double saida[]=0; // OUTPUT VECTOR
---
> double *y; // AUX VECTOR TO RECEIVE X VECTOR
> double *saida; // OUTPUT VECTOR
21c21
< coef[i] = 1/m;
---
> coef[i] = 1.0/m;
29c29
... this zone has heavy edits because it was completely wrong
>
36c41
< aux= aux + coef[n] * y[n];
---
> aux += coef[n] * y[n]; // more C-like
44c49
< fwrite(*saida, sizeof(double),itera,arq);
---
> fwrite(saida, sizeof(double),itera,arq); // already a pointer
45a51,53
> free(saida); // free memory
> free(y);
> free(x);
这是固定代码。请注意,我不确定它是否有效,但它可以编译。如果出现问题,请使用调试器
#include <stdio.h>
#include <stdlib.h>
#define m 16 // MEDIA LENGTH
int main()
{
short *x; // X VECTOR = 0
double coef[m]; // COEF VECTOR = 0
int i; // FOR COUNT VARIABLE
int n; // FOR COUNT VARIABLE
int itera; // LENGTH OF THE INPUT FILE
double aux; // AUX VARIABLE TO MAKE THE SUM
double *y; // AUX VECTOR TO RECEIVE X VECTOR
double *saida; // OUTPUT VECTOR
FILE *arq; // POINTER TO THE FILE
for (i = 0; i < m; i++) {
coef[i] = 1.0/m;
}
arq = fopen("sweep_100_3400.pcm", "rb");
if (arq == NULL)
{
printf("ERROR WHILE OPENING THE FILE\n");
return;
}
// compute size of file
fseek(arq,0,SEEK_END);
itera = ftell(arq)/sizeof(short);
rewind(arq);
// alloc mem for x, read the vector from input file
x = malloc(itera*sizeof(short));
fread(x,sizeof(short),itera,arq);
fclose(arq);
// alloc mem for y
y = malloc(itera*sizeof(double));
saida = malloc(itera*sizeof(double));
for (i=0; i < itera; i++) {
y[0] = x[i];
aux=0;
for (n=0; n<m; n++){
aux += coef[n] * y[n];
}
saida[i]=aux;
for (n=m; n <2; n--){
x[n] = x[n-1];
}
}
arq=fopen("saida_medial_movel_c.pcm","wb");
fwrite(saida, sizeof(double),itera,arq);
fclose(arq);
free(saida);
free(y);
free(x);
}
我的建议是宁愿使用 C++,因为有了 std::vector
和 std::string
,您可以更快地移植东西,并且崩溃、内存泄漏和未定义行为的风险更小。嗯,也许下次...