Transferred efficient multiplication algorithm from MATLAB to Fortran does not match

Viewed 103

Related to this question Thanks to the idea of @veryreverie, I was eventually able to multiply the block diagonal matrix by a vector with some modifications. (Matrix structure is at the end of post). However something is wrong. When I run the algorithm in MATLAB, there no issues.

The difference in direct multiplication and my result of C'*x - bn is within 1e-15 range due to machine addition non-associativity. However, when trying the same thing in Fortran it differs significantly, up to NaN value:

f90 code:

module RHS
implicit none
contains
subroutine RHS_eval(m,n,C,MM,q,LAP,BCterm,ADV,bn)

real*8, intent (in) :: x(:),C(:,:)
real*8, intent (out) :: bn(:)
integer*8 :: row, col
integer*8, intent (in) :: m,n

integer*8 :: offset, blkSz, blkShft, i
integer*8 :: xstart, ystart

bn = 0

bn(1:(m-1)*(n-1)) = bn(1:(m-1)*(n-1)) + x(1:(m-1)*(n-1));
bn(1:(m-1)*(n-1)) = bn(1:(m-1)*(n-1)) - x(m:(m-1)*n);

blkSz = m;
offset = (m-1)*(n);
blkShft = m-1;

do i = 1,(n-1)
    xstart = offset + blkSz*(i-1)+1;
    ystart = (i-1)*(m-1)+1;
    bn(ystart:ystart+blkShft-1) = bn(ystart:ystart+blkShft-1) - x(xstart:xstart+blkShft-1);
    bn(ystart:ystart+blkShft-1) = bn(ystart:ystart+blkShft-1) + x(xstart+1:xstart+blkShft);
enddo

end subroutine RHS_eval

end module RHS

MATLAB code:

n = 15; m = 10; 
x = (10*rand((m-1)*n+(n-1)*m,1));
bn = zeros((n-1)*(m-1),1);

bn(1:(m-1)*(n-1)) = bn(1:(m-1)*(n-1)) + x(1:(m-1)*(n-1));
bn(1:(m-1)*(n-1)) = bn(1:(m-1)*(n-1)) - x(m:(m-1)*n);

blkSz = m;
offset = (m-1)*(n);
blkShft = m-1;

for i = 1:(n-1)
    xstart = offset + blkSz*(i-1)+1;
    ystart = (i-1)*(m-1)+1;
    bn(ystart:ystart+blkShft-1) = bn(ystart:ystart+blkShft-1) - x(xstart:xstart+blkShft-1);
    bn(ystart:ystart+blkShft-1) = bn(ystart:ystart+blkShft-1) + x(xstart+1:xstart+blkShft);
end

We take the transpose of matrix C and multiply from RHS by a vector. There is no need to store the matrix since its structure is known. C

Fixed a tiny bit, at early iterations it kinda works as expected, the number shown is the difference between matmul and my multiplication algo maxval(abs(bn - matmul(transpose(C),(x))))

Initial

But starting at around 60th step starts to blow up

Further

This issue only happens for the case when m and n are not equal

0 Answers
Related