C中nxn矩阵的walsh表
我一直在试图理解n维的沃尔什表矩阵,因为我需要编写一个代码来生成任意给定顺序的沃尔什矩阵。到目前为止,我还没有写出一个有效的代码。有人能帮我做一下算法吗,或者对我下面的程序提出一些建议:(它适用于2x2和4x4,但不适用于8x8)C中nxn矩阵的walsh表,c,matrix,multidimensional-array,C,Matrix,Multidimensional Array,我一直在试图理解n维的沃尔什表矩阵,因为我需要编写一个代码来生成任意给定顺序的沃尔什矩阵。到目前为止,我还没有写出一个有效的代码。有人能帮我做一下算法吗,或者对我下面的程序提出一些建议:(它适用于2x2和4x4,但不适用于8x8) #包括 #包括 main() { /*程序变量 维度变量,n 循环变量i,j 沃尔什表a的二维数组[100][100]*/ int n,j,i,a[100][100]; clrsc(); //显示沃尔什表的用户输入 printf(“输入尺寸”); scanf(“%d”
#包括
#包括
main()
{
/*程序变量
维度变量,n
循环变量i,j
沃尔什表a的二维数组[100][100]*/
int n,j,i,a[100][100];
clrsc();
//显示沃尔什表的用户输入
printf(“输入尺寸”);
scanf(“%d”和“&n”);
//将行从0迭代到“n”
对于(i=0;i您应该将沃尔什代码的生成视为一个递归问题。首先生成2x2;然后生成4x4,以此类推。每次,通过在右上象限和左下象限中添加两个低阶块的副本,并在右下象限中添加其逆项,从上一个块生成下一个块你可以通过创建一次矩阵,然后以增加块大小的方式通过它来实现。下面是它的工作原理
更新了,因此它生成了您在wiki上看到的1-1
版本的代码
再次更新,使其能够获取矩阵大小的输入并生成任意大小的沃尔什矩阵;包括各种错误检查和其他酷技巧:
FINAL(?)UPDATERyker指出我的代码中有一个内存错误。我找到并修复了它-并用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...
}
作为参考,请参阅-我从中得出以下结论:
POSTSCRIPT
关于twoDmatrix()的一个注记
函数。我编写这个函数是因为没有直接的方法在C中分配一个大小未知的2D矩阵。所以这个函数创建一个指向int
的指针数组-矩阵中的每一行一个指针;它还分配一个内存块-数组中的每个元素一个。然后它将一个指针与开始的o相关联f矩阵中的每一行,以便您可以使用通常的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)使用更多块格式化{…}
以提高可读性
2)使用memset()为所有元素初始化数组a[100][100]
3)添加了一个额外的getchar()
(我的系统使用它而不是getch()
),并注释了clrsc()
它运行了4x4和8x8(但输出看起来不正确,您还有更多的工作要做):
main()
{
/*程序变量
维度变量,n
循环变量i,j
沃尔什表a的二维数组[100][100]*/
int n,j,i,a[100][100];
//clrsc();
//显示沃尔什表的用户输入
memset(a,0,100*100);
printf(“输入尺寸”);
scanf(“%d”和“&n”);
//将行从0迭代到“n”
对于(i=0;i请更具体地说明什么不符合要求。错误是什么???我的代码应该可以生成nxn沃尔什矩阵,但算法只能工作到4x4矩阵,我需要一些关于算法的帮助。(此代码本身没有错误。)我已经更新了我的代码,使其以您要求的形式生成输出。非常感谢。非常有帮助。我将对其进行修改,以将维度作为输入。谢谢。@Floris-如果我可以再次单击您,我会的。关于C多维矩阵的解释非常好。我将删除所有其他注释。@Ryker-没有我们感兴趣的交换,我将我不可能成为这个答案。所以谢谢你!
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]
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();
}