| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 3461 人关注过本帖
标题:矩阵相乘运算
只看楼主 加入收藏
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
那就别说是矩阵乘法问题了嘛,成心哄人下陷阱不是。

授人以渔,不授人以鱼。
2011-09-24 13:43
c821101017
Rank: 2
等 级:论坛游民
帖 子:33
专家分:10
注 册:2011-9-21
收藏
得分:0 
回复 11楼 TonyDeng
    你能不能解决啊,我本科是学数学的,现在好久没接触,很多基础东西都忘了,真是惭愧啊……
2011-09-24 13:53
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:0 
也不是很难求。数学模型是这样的:
A[m*n]=B[m*l]C[l*n]([] 里的是维数)
已知 A, C 求 B。现在就是要求 m*l 个未知数。

把 B 的每一行看成一组,第 i 行乘以 C 的每一列,结果就是 A 的第 i 行。这是一个 m 元的线性方程组(共有 n 个方程,其中可能有冗余方程)。
如果对 B 的每一行都求解,一共是 l 组方程,就可以得到全部 m*l 个未知数了。
一般来说解 l 组方程是很费劲的,不过这 l 组方程的系数矩阵都一样,就是右端项不同。所以求起来跟只解一组方程耗时差不多。

解这些方程组,可以用任何你会的线性方程组解法。比如高斯消元呀,LU分解之类的。
2011-09-24 13:58
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
我更惭愧,一直都没遇上要用到矩阵的东西,现学也来不及啦。看有没有别人熟悉这个数学的吧。

授人以渔,不授人以鱼。
2011-09-24 14:00
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
回复 13楼 pangding
呵呵,居然跟我猜的方向一样,也是归结到解线性方程组上,还想有没有别的办法呢。

[ 本帖最后由 TonyDeng 于 2011-9-24 14:13 编辑 ]

授人以渔,不授人以鱼。
2011-09-24 14:02
c821101017
Rank: 2
等 级:论坛游民
帖 子:33
专家分:10
注 册:2011-9-21
收藏
得分:0 
回复 13楼 pangding
    能给个联系方式吗?我把程序发给你,你帮我看下,好吗?
2011-09-24 14:12
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:5 
呵呵。你本科还是数学系的,那不错。我也是。
其实你基础要好,可以自己学学矩阵论之类的东西。里面有广义逆矩阵的概念。这样长方形的矩阵也能做很多运算了。
13楼那么讲,应该有点线性代数基础的人都能看懂。其实矩阵这东西,归了包根都跑不开线性方程组这些基本的东西上去。

不过我估计我没什么时间帮你看程序。我现在也在读研,刚开学还是挺忙的。


[ 本帖最后由 pangding 于 2011-9-24 14:23 编辑 ]
2011-09-24 14:18
c821101017
Rank: 2
等 级:论坛游民
帖 子:33
专家分:10
注 册:2011-9-21
收藏
得分:0 
回复 17楼 pangding
    13楼的思路我明白,我的盲区在于怎么用c语言实现线性方程组的求解,而且该线性方程组的方程个数要小于变元数,我大致算了下,这个方程组解不唯一;还有由于里面的系数都是非0即1,所以其实它的加法是模2加的,即:1+1=0,0+1=1;
2011-09-24 14:29
c821101017
Rank: 2
等 级:论坛游民
帖 子:33
专家分:10
注 册:2011-9-21
收藏
得分:0 
    我将程序附上来吧,可能有点冗长,大家帮忙看下:
程序代码:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<math.h>
int r[5];
/*************多项式相乘模块****************/
void pmul(int k[],int x,int t[],int y,int n[],int z)
{
    int i,j;
    for(i=0;i<z;i++)
        n[i]=0;
    for(i=0;i<x;i++)
        for(j=0;j<y;j++)
            n[i+j]=n[i+j]+k[i]*t[j];
    return;
}
/*************多项式相除模块**************/
void pdiv(int n[],int x,int m[],int y,int r[],int l)
{
    int i,k;
    for(i=x-1;i>=0;i--)
        if(n[i]!=0)
        {
            k=i;
            printf("%d\n",k);
            break;
        }
    while(k>=5)
    {
        for(i=k;i>=k-5;i--)
        {
            n[i]=n[i]^m[y-1-k+i];
        }
        for(i=k;i>=k-5;i--)
            if(n[i]!=0)
            {
                k=i;
//                printf("%d\n",k);
                break;
            }
    }
    for(i=l-1;i>=0;i--)
        r[i]=n[i];
    return;
}
void main()
{
    int i,j,z;
    char flag='Y';
    while(flag=='Y')
    {
        int n[15];//整个码长,用于存放多项式相乘后各项的系数.
        int k[10];//信息码系数数组.
        int t[6]={0,0,0,0,0,1};//与信息码多项式相乘的多项式的各项的系数,即x^5.
        FILE *fp;
        fp=fopen("a.txt","w");
        srand(time(0));
        printf("The Cofficient of the information code is: \n");
        for(i=0;i<10;i++)
        {
            k[i]=rand()%2;
            printf("%d",k[i]);
        }
        printf("\n");
        pmul(k,10,t,6,n,15);//多项式相乘模块的调用.
        printf("The Cofficient of the total code is: \n");
        for(i=0;i<15;i++)
        {
            printf("%d",n[i]);
            fprintf(fp,"%d",n[i]);
        }
        fprintf(fp,"\n");
        printf("\n");
        fclose(fp);
        int m[6]={1,0,1,0,1,1};
//        static int r[5];
        pdiv(n,15,m,6,r,5);//多项式相除模块的调用.
        printf("The Cofficient of the array r is: \n");
        for(i=0;i<=4;i++)
            printf("%d",r[i]);
        printf("\n");
        /**********将文件中的数据读出来**********/
        fp=fopen("a.txt","rb");
        printf("The Cofficient that we read from the file is: \n");
//        fscanf(fp,"%s",n);//读出文件中的二进制代码.
        for(i=0;i<15;i++)
        {
            if(fscanf(fp,"%c",&n[i])==EOF)//改为每次读出一个字符.
                break;
            printf("%c",n[i]);//同样以字符格式输出.
        }
        printf("\n");
        for(i=0;i<15;i++)
        {
            n[i]=n[i]-48;//将字符型转换成整形.
            printf("%d",n[i]);
        }
        printf("\n");
        fclose(fp);
        /**********将余多项式中的各项系数赋值给信息多项式中的系数************/
        for(i=0;i<=4;i++)
            n[i]=r[i];
        printf("The Cofficient that we need lastly is: \n");
        for(i=0;i<15;i++)
            printf("%d",n[i]);
        printf("\n\n");
        /*************对发送的码组加入误码,即定义为接收到的码组s[15]**************/
        int s[15];    //接收到的码组;
        printf("The Code Group that we recived is: \n");
        for(i=0;i<=4;i++)
            s[i]=n[i];
        for(i=5;i<=14;i++)
            s[i]=rand()%2;     //加入误码过程.
        for(i=0;i<=14;i++)
            printf("%d",s[i]);
        printf("\n");
        /************根据接收到的码组来解得校验子q[5]*************/
        int q[5];
        pdiv(s,15,m,6,q,5);        //调用多项式相除模块.
        printf("Calibration sub- is: \n");        //输出校验子.
        for(i=0;i<=4;i++)
            printf("%d",q[i]);
        printf("\n");
        /************根据求得的校验子来判别接收是否有误******************/
        for(i=0;i<=4;i++)
            if(q[i]!=0)
            {
                printf("The Code Group that we recived isn't equal to the Code Group that we sent.\n\n");
                break;
            }
        /************求生成矩阵G的多项式G(x)*******************/
        static int a[10];   //对x^i进行数组定义;
        int G[15];
        FILE *fp1;
        fp1=fopen("b.txt","w");        //将每一个生成的G(x)的系数数组输出到b.txt中;
        for(i=9;i>=0;i--)
        {
            a[i]=1;
            pmul(a,10,m,6,G,15);
            a[i]=0;                //每一次循环之后都要对a[10]重置0;
            for(j=14;j>=0;j--)
                fprintf(fp1,"%d ",G[j]);        //输出到文件中;
            fprintf(fp1,"\n");
        }
        fclose(fp1);
        fp1=fopen("b.txt","r");
        printf("The Matrix that we read from the file is: \n");
        int b[10][15];            //将生成矩阵G从文件读出来并存放在定义的矩阵b中;
        for(i=0;i<=9;i++)
        {
            for(j=0;j<=14;j++)
            {
                fscanf(fp1,"%d",&b[i][j]);
                printf("%d ",b[i][j]);
            }
            printf("\n");
        }
        fclose(fp1);
        /***********将生成矩阵G转换成典型生成矩阵b**************/
        for(i=9;i>=0;i--)
            for(j=i-1;j>=0;j--)
                for(z=0;z<=14;z++)
                {
                    if(b[j][i]==b[i][i])                //主要是消去对应位置上的1使其变为0;
                        b[j][z]=b[j][z]^b[i][z];
                }
        printf("The Matrix b that we convert from Matrix G is: \n");
        for(i=0;i<=9;i++)
        {
            for(j=0;j<=14;j++)
                printf("%d ",b[i][j]);
            printf("\n");
        }
        /***********将典型生成矩阵转换成监督矩阵H**************/
        int c[10][5],d[5][10];
        printf("The Matrix Q is: \n");
        for(i=0;i<=9;i++)
        {
            for(j=10;j<=14;j++)
            {
                c[i][j-10]=b[i][j];
                printf("%d ",c[i][j-10]);
            }
            printf("\n");
        }
        printf("The Matrix P is: \n");
        for(i=0;i<=4;i++)
        {
            for(j=0;j<=9;j++)
            {
                d[i][j]=c[j][i];
                printf("%d ",d[i][j]);
            }
            printf("\n");
        }
        printf("The Monitoring Matrix H is: \n");
        int H[5][15];
        for(i=0;i<=4;i++)
        {
            for(j=0;j<=9;j++)
                H[i][j]=d[i][j];
            for(j=10;j<=14;j++)
            {
                if((i+10)==j)
                    H[i][j]=1;
                else
                    H[i][j]=0;
            }
        }
        for(i=0;i<=4;i++)
        {
            for(j=0;j<=14;j++)
                printf("%d ",H[i][j]);
            printf("\n");
        }
        /*************求解错误图样E:其中q[]=E[]*D(未完成)***************/
        printf("The Transpose of Matrix H is: \n");
        int D[15][5],E[15];
        for(i=0;i<=14;i++)
        {
            for(j=0;j<=4;j++)
            {
                D[i][j]=H[j][i];
                printf("%d ",D[i][j]);
            }
            printf("\n");
        }
        printf("Do you want to continue?If yes,press Y,if not,press N.\n");
        scanf("%c",&flag);
        getchar();
        if(flag=='Y')
            continue;
        else break;
    }
}


2011-09-24 14:33
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:0 
哦。你这问题工程背景强的很,还是有限二元域上的矩阵。那可能通论里的方法只能提供个思路。
0-1矩阵是类特殊的矩阵,相关方面有不少研究成果了,这些东西我也没专门学过,毕竟我也不是专门搞这个。有些东西自己去查查资料呀,都研究生了,得有点研究能力不是~~

果然是编码理论的那些东西,这个我当年倒是学过,不过不复习复习肯定记不清了。你去查查编码理论的书唄,相关的算法应该都是现成的,而且好多东西其实是向量而不是矩阵了之后,算着差能快很多呢。


[ 本帖最后由 pangding 于 2011-9-24 14:40 编辑 ]
2011-09-24 14:36
快速回复:矩阵相乘运算
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.036385 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved