Blitz++ 矩阵相乘(张量运算) 示例

//   整理 by RobinKin
None.gif
  //   Blitz++ 张量计算的示例  
ExpandedBlockStart.gif 
/* ****************************************************************************
InBlock.gif * matmult.cpp     Blitz++ tensor notation example
InBlock.gif *****************************************************************************
InBlock.gif * This example illustrates the tensor-like notation provided by Blitz++.
ExpandedBlockEnd.gif 
 */ 

None.gif 
None.gif#include 
  <   blitz   /   array.h   >  
None.gif#include 
  <   iostream   >  
None.gif 
None.gif 
using       namespace    blitz;
None.gif
None.gif
  int    main()
ExpandedBlockStart.gif
  {
InBlock.gif     //  Create two 4x4 arrays.  We want them to look like matrices, so
InBlock.gif    
 //  we'll make the valid index range 1..4 (rather than 0..3 which is
InBlock.gif    
 //  the default). 
InBlock.gif 

InBlock.gif    Range r( 1 , 4 );
InBlock.gif    Array < float , 2 >  A(r,r), B(r,r);
InBlock.gif
InBlock.gif     //  The first will be a Hilbert matrix:
InBlock.gif    
 // 
InBlock.gif    
 //  a   =   1
InBlock.gif    
 //   ij   -----
InBlock.gif    
 //        i+j-1
InBlock.gif    
 // 
InBlock.gif    
 //  Blitz++ provides a set of types { firstIndex, secondIndex, dot.gif }
InBlock.gif    
 //  which act as placeholders for indices.  These can be used directly
InBlock.gif    
 //  in expressions.  For example, we can fill out the A matrix like this: 
InBlock.gif 

InBlock.gif    firstIndex i;     //  Placeholder for the first index 
InBlock.gif 
    secondIndex j;    //  Placeholder for the second index 
InBlock.gif 

InBlock.gif    A  =   1.0   /  (i + j - 1 );
InBlock.gif
InBlock.gif    cout  <<   " A =  "   <<  A  <<  endl;
InBlock.gif
InBlock.gif     //  A = 4 x 4
InBlock.gif    
 //          1       0.5  0.333333      0.25
InBlock.gif    
 //        0.5  0.333333      0.25       0.2
InBlock.gif    
 //   0.333333      0.25       0.2  0.166667
InBlock.gif    
 //       0.25       0.2  0.166667  0.142857
InBlock.gif
InBlock.gif    
 //  Now the A matrix has each element equal to a_ij = 1/(i+j-1).
InBlock.gif
InBlock.gif    
 //  The matrix B will be the permutation matrix
InBlock.gif    
 // 
InBlock.gif    
 //  [ 0 0 0 1 ]
InBlock.gif    
 //  [ 0 0 1 0 ]
InBlock.gif    
 //  [ 0 1 0 0 ]
InBlock.gif    
 //  [ 1 0 0 0 ]
InBlock.gif    
 // 
InBlock.gif    
 //  Here are two ways of filling out B: 
InBlock.gif 

InBlock.gif    B  =  (i  ==  ( 5 - j));          //  Using an equation -- a bit cryptic 
InBlock.gif 

InBlock.gif    cout  <<   " B =  "   <<  B  <<  endl;
InBlock.gif
InBlock.gif     //  B = 4 x 4
InBlock.gif    
 //          0         0         0         1
InBlock.gif    
 //          0         0         1         0
InBlock.gif    
 //          0         1         0         0
InBlock.gif    
 //          1         0         0         0 
InBlock.gif 

InBlock.gif    B  =   0 ,  0 ,  0 ,  1 ,            //  Using an initializer list 
InBlock.gif 
         0 ,  0 ,  1 ,  0 ,           
InBlock.gif         0 ,  1 ,  0 ,  0 ,
InBlock.gif         1 ,  0 ,  0 ,  0 ;
InBlock.gif
InBlock.gif    cout  <<   " B =  "   <<  B  <<  endl;
InBlock.gif
InBlock.gif     //  Now some examples of tensor-like notation. 
InBlock.gif 

InBlock.gif    Array < float , 3 >  C(r,r,r);   //  A three-dimensional array: 1..4, 1..4, 1..4 
InBlock.gif 

InBlock.gif    thirdIndex k;              //  Placeholder for the third index
InBlock.gif
InBlock.gif    
 //  This expression will set
InBlock.gif    
 // 
InBlock.gif    
 //  c    = a   * b
InBlock.gif    
 //   ijk    ik    kj
InBlock.gif
InBlock.gif 
 //    C = A(i,k) * B(k,j); 
InBlock.gif 
   cout  <<   " C =  "   <<  C  <<  endl;
InBlock.gif
InBlock.gif
InBlock.gif     //  In real tensor notation, the repeated k index would imply a
InBlock.gif    
 //  contraction (or summation) along k.  In Blitz++, you must explicitly
InBlock.gif    
 //  indicate contractions using the sum(expr, index) function: 
InBlock.gif 

InBlock.gif    Array < float , 2 >  D(r,r);
InBlock.gif    D  =  sum(A(i,k)  *  B(k,j), k); // 指标收缩, 计算矩阵积
InBlock.gif
InBlock.gif    
 //  The above expression computes the matrix product of A and B. 
InBlock.gif 

InBlock.gif    cout  <<   " D =  "   <<  D  <<  endl;
InBlock.gif
InBlock.gif     //  D = 4 x 4
InBlock.gif    
 //       0.25  0.333333       0.5         1
InBlock.gif    
 //        0.2      0.25  0.333333       0.5
InBlock.gif    
 //   0.166667       0.2      0.25  0.333333
InBlock.gif    
 //   0.142857  0.166667       0.2      0.25
InBlock.gif
InBlock.gif    
 //  Indices like i,j,k can be used in any order in an expression.
InBlock.gif    
 //  For example, the following computes a kronecker product of A and B,
InBlock.gif    
 //  but permutes the indices along the way: 
InBlock.gif 

InBlock.gif    Array < float , 4 >  E(r,r,r,r);     //  A four-dimensional array 
InBlock.gif 
    fourthIndex l;                 //  Placeholder for the fourth index 
InBlock.gif 

InBlock.gif    E  =  A(l,j)  *  B(k,i); // 指标轮换
InBlock.gif
 // cout << "E = " << E << endl;
InBlock.gif
InBlock.gif
InBlock.gif    
 //  Now let's fill out a two-dimensional array with a radially symmetric
InBlock.gif    
 //  decaying sinusoid. 
InBlock.gif 

InBlock.gif     int  N  =   64 ;                    //  Size of array: N x N 
InBlock.gif 
    Array < float , 2 >  F(N,N);
InBlock.gif     float  midpoint  =  (N - 1 ) / 2 .;
InBlock.gif     int  cycles  =   3 ;
InBlock.gif     float  omega  =   2.0   *  M_PI  *  cycles  /   double (N);
InBlock.gif     float  tau  =   -   10.0   /  N;
InBlock.gif
InBlock.gif    F  =  cos(omega  *  sqrt(pow2(i - midpoint)  +  pow2(j - midpoint)))
InBlock.gif         *  exp(tau  *  sqrt(pow2(i - midpoint)  +  pow2(j - midpoint)));
InBlock.gif
InBlock.gif // cout << "F = " << F << endl; 
InBlock.gif 

InBlock.gif     return   0 ;
ExpandedBlockEnd.gif

None.gif 
//   输出  
None.gif 
  =       4    x    4   [            1             0.5        0.333333            0.25               0.5        0.333333            0.25             0.2          0.333333            0.25             0.2        0.166667              0.25             0.2      0.166667        0.142857    ]
None.gif
None.gif
  =       4    x    4  
None.gif[         
  0               0               0               1    
None.gif          
  0               0               1               0    
None.gif          
  0               1               0               0    
None.gif          
  1               0               0               0    ]
None.gif
None.gif
None.gif
  =       4    x    4  
None.gif[         
  0               0               0               1    
None.gif          
  0               0               1               0    
None.gif          
  0               1               0               0    
None.gif          
  1               0               0               0    ]
None.gif
None.gif
None.gif
  =       4    x    4  
None.gif[      
  0.25        0.333333             0.5               1    
None.gif        
  0.2            0.25        0.333333             0.5    
None.gif   
  0.166667             0.2            0.25        0.333333    
None.gif   
  0.142857        0.166667             0.2            0.25    ]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值