Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MATLAB: overriding table() methods

SETUP Win7 64b, R2015b, 16 GB of RAM, CPU i7-2700

The table() is a fundamental Matlab class which is also sealed, hence I cannot subclass it.

I want to fix some methods of this class and add new ones. For instance, table.disp() is fundamentally broken, e.g. try NOT disp(table(rand(1e7,1))), or forget the ; in the command window. The variable takes only 76 MB in RAM but the display is unbuffered and it will stall your system!

  1. Can I override methods like table.disp() without writing into matlabroot\toolbox\matlab\datatypes\@table?
  2. Can I extend the table class with a new method under C:\MATLAB\@table\ismatrixlike.m? Why do I get

    ismatrixlike(table)
    Undefined function 'ismatrixlike' for input arguments of type 'table'. 
    

    Obviously, I did

    addpath C:\MATLAB\
    rehash toolboxcache
    

    I also tried clear all.

    The path has (alphabetic) precedence over matlabroot, but is missing a table.m class definition. If I add the native class defition to C:\MATLAB\@table, then I can run my new method (after a clear all). However:

    >> methods(table)
    
    Methods for class table:
    
    classVarNames   ismatrixlike    table           varfun          
    convertColumn   renameVarNames  unstack      
    

    only lists the methods in the new \@table folder, even though (some of) the old methods still work, e.g.

    size(table)
    

    This partly solves the problem, since now, the native \@table\private folder is not accessible anymore and therefore many native methods are broken!

Why am I doing this? Because I do not want to wait another 2 years before the table() is fixed. I already lost entire days because I simply forgot a ; in the command window and I cannot force a restart on my pc if it is running multiday simulations, but I have to wait for the disk-swap to end :(.

APPENDIX More context about disp(table(rand(1e7,1))). This is what happens when I hit it (and luckily I am fast enough to CTRL-C out of it):

enter image description here

The culprit is line 172 of table.disp() which converts the numeric array into a cellstring (with the padding too!):

[cells, err, isLeft] = sprintfc(f, x, b);
like image 566
Oleg Avatar asked Jan 23 '16 16:01

Oleg


1 Answers

After experimenting with several alternatives, I adopted the solution that intereferes the least with Matlab's native @table implementation and it's easily removed if things go awry.

The solution:

  • copy the whole @table folder, i.e. fullfile(matlabroot,'toolbox','matlab','datatypes','@table'), into a destination where you have write permissions.

    I picked the destination to be fullfile(matlabroot,'toolbox','local','myfiles') since I do not have to bother with OS cross-compatibility, i.e. matlabroot takes care of that for me.

  • paste into the destination your @table folder with the new, overloaded and overriding methods (partially overwriting the copied original files)

  • add the destination to the matlab path, before the original @table, e.g. addpath your_destination -begin

Effects, pros and cons:

  • The native @table class/methods are now shadowed, try e.g. which table -all. However, this effect is quite clear, easily detectable and easily removed (delete destintation and remove path);
  • No weird conflicts between native @table (now shadowed) and new @table;
  • All methods, new and old, are visible, try methods(table);
  • Private table methods are accessible...
  • ... but you are forced to use them.
  • Exposing the new methods (user-implemented) to the private ones requires more maintenance and direct handling of version conflicts in the table implementations.
  • You need write permissions on some eligible destination.

For those interested about the details, you can look into, https://github.com/okomarov/tableutils. Specifically the install_tableutils (the readme might not be updated).

like image 154
Oleg Avatar answered Oct 09 '22 06:10

Oleg