full implementation of cachematrix