void sub(const Array2D<E> &aobj,const Array2D<E> &bobj,Array2D<E> &cobj) { int astarti=aobj.low1(),astartj=aobj.low2(),arow=aobj.size1(),acol=aobj.size2(); int bstarti=bobj.low1(),bstartj=bobj.low2(),brow=bobj.size1(),bcol=bobj.size2(); //Array2D<E> c(0,arow-1,0,acol-1); cobj.init(0,arow-1,0,acol-1); for(int i=0;i<arow;i++) { for(int j=0;j<acol;j++) cobj(i,j)=aobj(i+astarti,j+astartj)-bobj(i+bstarti,j+bstartj); } }
void mul(const Array2D<E> &a,const Array2D<E> &b,Array2D<E> &obj) { int arow=a.size1(); int acol=a.size2(); int brow=b.size1(); int bcol=b.size2(); OGDF_ASSERT(arow==acol && acol==brow && brow==bcol); //checking matrix is square and equal or not int ai=a.low1(),aj=a.low2(),bi=b.low1(),bj=b.low2(); obj.init(0,arow-1,0,arow-1,0); for(int i=0;i<arow;i++) for(int j=0;j<acol;j++) for(int k=0;k<brow;k++) obj(i,j)+=a(i+ai,k+aj)*b(k+bi,j+bj); }
void strassen(const Array2D<E> &a,const Array2D<E> &b,Array2D<E> &c) { int astarti=a.low1(),astartj=a.low2(),arow=a.size1(),acol=a.size2(); int bstarti=b.low1(),bstartj=b.low2(),brow=b.size1(),bcol=b.size2(); OGDF_ASSERT(arow==acol && acol==brow && brow==bcol); //checking matrix is square and equal or not if(arow<=2) { mul(a,b,c); // naive method for calculating matrix multiplication of size less than or equal to 4 } else { int val1=arow/2-1; int val2=arow-1; Array2D<E> a11,a12,a21,a22,b11,b12,b21,b22; submatrix(a,astarti,astartj,astarti+val1,astartj+val1,a11); submatrix(a,astarti,astartj+val1+1,astarti+val1,astartj+val2,a12); submatrix(a,astarti+val1+1,astartj,astarti+val2,astartj+val1,a21); submatrix(a,astarti+val1+1,astartj+val1+1,astarti+val2,astartj+val2,a22); submatrix(b,bstarti,bstartj,bstarti+val1,bstartj+val1,b11); submatrix(b,bstarti,bstartj+val1+1,bstarti+val1,bstartj+val2,b12); submatrix(b,bstarti+val1+1,bstartj,bstarti+val2,bstartj+val1,b21); submatrix(b,bstarti+val1+1,bstartj+val1+1,bstarti+val2,bstartj+val2,b22); //calulating p(i) for applying strassen method Array2D<E> obj1,obj2; add(a11,a22,obj1); add(b11,b22,obj2); Array2D<E> p1,p2,p3,p4,p5,p6,p7; strassen(obj1,obj2,p1); add(a21,a22,obj1); strassen(obj1,b11,p2); sub(b12,b22,obj2); strassen(a11,obj2,p3); sub(b21,b11,obj2); strassen(a22,obj2,p4); add(a11,a12,obj1); strassen(obj1,b22,p5); sub(a21,a11,obj1); add(b11,b12,obj2); strassen(obj1,obj2,p6); sub(a12,a22,obj1); add(b21,b22,obj2); strassen(obj1,obj2,p7); //calculating submatrix of final result matrix Array2D<E> c11,c22,c21,c12,cnn; add(p1,p4,c11); sub(c11,p5,cnn); add(cnn,p7,c11); add(p3,p5,c12); add(p2,p4,c21); add(p1,p3,c22); add(c22,p6,cnn); sub(cnn,p2,c22); c.init(0,val2,0,val2); //function call for info of submatrices int c11i=c11.low1(),c11j=c11.low2(); int c12i=c12.low1(),c12j=c12.low2(); int c21i=c21.low1(),c21j=c21.low2(); int c22i=c22.low1(),c22j=c22.low2(); //Method for grouping of submatrix into 1 for(int i=0;i<=val1;i++) { for(int j=0;j<=val1;j++) { c(i,j)=c11(c11i+i,c11j+j); c(i,j+val1+1)=c12(c12i+i,c12j+j); c(i+val1+1,j)=c21(c21i+i,c21j+j); c(i+val1+1,j+val1+1)=c22(c22i+i,c22j+j); } } } }