我一直试图理解n维的沃尔什表矩阵,因为我需要编写一个代码,为任何给定的顺序生成沃尔什矩阵。到目前为止,我没有编写一个有效的代码。任何人都可以帮我解决这个问题,或者建议我的程序如下:(适用于2x2和4x4,但8x8无效)
#include<stdio.h>
#include<conio.h>
main()
{
/* Program variables
Dimension variable, n
Loop variables i,j
Two dimensional array for walsh table a[100][100] */
int n,j,i,a[100][100];
clrscr();
// User input to display walsh table
printf("enter the size ");
scanf("%d",&n);
// Iterate rows from 0 to 'n'
for(i=0;i<n;i++)
{
// Iterate columns from 0 to 'n' for each row 'i'
for(j=0;j<n;j++)
{
if(i%2==1 && j%2==1) // for both i & j not divisible by 2, initialize array elements with -1
a[i][j] = -1;
else if(i/2==1 && j/2==1){ // for both i & j, if completely divisble by 2 and dividend is 1
if(j == 3 && i == 3){
a[i][j]=1;
}
else
a[i][j] = -1;
}
else
a[i][j] = 1; // default case initialized to 1
}
a[3][3] = 1;
}
// Output complete walsh table
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
printf("\t%d",a[i][j]);
}
// go to next line after every row
printf("\n");
}
getch();
}
答案 0 :(得分:1)
您应该将沃尔什代码的生成视为递归问题。首先你生成2x2;从那里你生成4x4等。每次,通过在右上角和左下象限中添加较小阶块的两个副本,从右上角生成下一个块,并在右下角添加其反转象限。您可以通过创建一次矩阵并逐步增加块大小来完成此操作。这是如何工作的
更新,因此它会生成您在wiki上看到的1 -1
版代码;
再次更新使其能够获取矩阵大小的输入并生成任意大小的Walsh矩阵;包括各种错误检查和其他很酷的技巧:
FINAL(?)UPDATE Ryyker指出我的代码中存在内存错误。我发现并修复了它 - 并使用valgrind
进行了检查以确定。现在似乎工作正常。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int **twoDmatrix(int m, int n) {
// create a 2D matrix of arbitrary dimensions
int ii, **M;
M = malloc(m * sizeof(int**));
M[0] = malloc(m*n*sizeof(int*));
for(ii=1; ii<m; ii++) {
M[ii] = M[0] + ii * n;
}
return M;
}
void free2D(int** M) {
// free memory allocated by twoDmatrix()
free(M[0]);
free(M);
}
int isPow2(int n) {
// return 1 if the argument is a valid (positive) power of 2
if(n<=1) return 0;
while(n>1) {
if (n%2==1) return 0;
n = n/2;
}
return 1;
}
void emptyBuf(void) {
while(getchar()!='\n');
return;
}
int main(void) {
int **W;
int N;
int power = 1;
int i,j,k,l,p=0;
while(1==1) {
printf("enter the size of the matrix - must be a positive power of 2\n");
if(scanf("%d", &N)!=1) {
printf("unable to scan input\n");
emptyBuf();
continue;
}
if (!isPow2(N)) {
printf("%d is not a valid power of 2\n", N);
continue;
}
break; // valid input: go on
}
W = twoDmatrix(N,N); // allocate memory for 2D matrix
W[0][0]=1; // this is the 1x1 Walsh code...
while (power < N) {
for(i=0; i<2; i++) {
for(j=0; j<2; j++) {
if (!(i==0 && j==0)) {
for(k=0; k<power; k++) {
for(l=0; l<power; l++) {
if (i==1 && j == 1) {
W[i*power+k][j*power+l] = -W[k][l]; // invert signal
}
else {
W[i*power+k][j*power+l] = W[k][l]; // copy signal
}
}
}
}
}
}
power *=2; // double matrix and repeat
}
// print out result
for(i=0; i<N; i++) {
for(j=0; j<N; j++) {
printf("%2d ", W[i][j]); // <<<<< updated
}
printf("\n");
}
free2D(W); // always remember to free your memory...
}
输出:
enter the size of the matrix - must be a positive power of 2
5
5 is not a valid power of 2
enter the size of the matrix - must be a positive power of 2
3
3 is not a valid power of 2
enter the size of the matrix - must be a positive power of 2
0
0 is not a valid power of 2
enter the size of the matrix - must be a positive power of 2
-4
-4 is not a valid power of 2
enter the size of the matrix - must be a positive power of 2
asdf
unable to scan input
enter the size of the matrix - must be a positive power of 2
asdfasdfasdfasdf
unable to scan input
enter the size of the matrix - must be a positive power of 2
16
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1
1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1
1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1
1 1 1 1 -1 -1 -1 -1 1 1 1 1 -1 -1 -1 -1
1 -1 1 -1 -1 1 -1 1 1 -1 1 -1 -1 1 -1 1
1 1 -1 -1 -1 -1 1 1 1 1 -1 -1 -1 -1 1 1
1 -1 -1 1 -1 1 1 -1 1 -1 -1 1 -1 1 1 -1
1 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1
1 -1 1 -1 1 -1 1 -1 -1 1 -1 1 -1 1 -1 1
1 1 -1 -1 1 1 -1 -1 -1 -1 1 1 -1 -1 1 1
1 -1 -1 1 1 -1 -1 1 -1 1 1 -1 -1 1 1 -1
1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1
1 -1 1 -1 -1 1 -1 1 -1 1 -1 1 1 -1 1 -1
1 1 -1 -1 -1 -1 1 1 -1 -1 1 1 1 1 -1 -1
1 -1 -1 1 -1 1 1 -1 -1 1 1 -1 1 -1 -1 1
供参考,请参阅http://my.fit.edu/~kostanic/Personal%20Communication%20Systems/ECE%205221%20-%20Lecture14.pptx - 我从中获取了以下内容:
<强> POSTSCRIPT 强>
关于twoDmatrix()
功能的说明。我编写了这个函数,因为没有直接的方法在C中分配未知大小的2D矩阵。所以这个函数创建了一个指向int
的指针数组 - 矩阵中每一行的一个指针;它还分配一块内存 - 一个用于数组中的每个元素。然后它将一个指针与矩阵中每行的开头相关联,以便您可以使用通常的W[i][j]
索引访问元素。这使得它看起来像数组的第一行真的很长(它指向整个NxN块),第二行稍短,等等。但它只是一个技巧,所以你可以访问数组的元素通常的语法。想象一下,你有一个3x3数组填充数字0到8 - 然后事情看起来像这样:
pointer values
W[0] 0 1 2
W[1] 3 4 5
W[2] 6 7 8
但另一种看待它的方式是:
0 1 2 3 4 5 6 7 8
^ W[0]
^W[1]
^W[2]
这意味着您可以访问元素W[0][6]
- 其值与W[1][3]
相同,后者再次与W[2][0]
相同。
当你不再需要这个功能时,你必须释放两块内存 - 首先是数据块,然后是指针块。这是free2D()函数的作用。
答案 1 :(得分:0)
修改 您的代码 :我做了三件事:
为了便于阅读, 1) 格式化了更多块{...}
使用a[100][100]
memset()
3) 添加了额外的getchar()
(我的系统使用的不是getch()
),并评论了clrscr()
它运行4x4和8x8 (但输出看起来不正确,你还有更多工作要做):
main()
{
/* Program variables
Dimension variable, n
Loop variables i,j
Two dimensional array for walsh table a[100][100] */
int n,j,i,a[100][100];
//clrscr();
// User input to display walsh table
memset(a, 0, 100*100);
printf("enter the size ");
scanf("%d",&n);
// Iterate rows from 0 to 'n'
for(i=0;i<n;i++)
{
// Iterate columns from 0 to 'n' for each row 'i'
for(j=0;j<n;j++)
{
if(i%2==1 && j%2==1) // for both i & j not divisible by 2, initialize array elements with -1
{
a[i][j] = -1;
}
else if(i/2==1 && j/2==1)
{ // for both i & j, if completely divisble by 2 and dividend is 1
if(j == 3 && i == 3)
{
a[i][j]=1;
}
}
else
{
a[i][j] = -1;
}
}
a[i][j] = 1; // default case initialized to 1
}
a[3][3] = 1;
// Output complete walsh table
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
printf("\t%d",a[i][j]);
}
// go to next line after every row
printf("\n");
}
getchar();
getchar();
}