{"id":26,"date":"2016-07-23T11:06:54","date_gmt":"2016-07-23T19:06:54","guid":{"rendered":"http:\/\/wonghoi.humgar.com\/blog\/?p=26"},"modified":"2025-12-01T17:53:29","modified_gmt":"2025-12-02T01:53:29","slug":"matlabs-cellfun-high-performance-trap","status":"publish","type":"post","link":"https:\/\/wonghoi.humgar.com\/blog\/2016\/07\/23\/matlabs-cellfun-high-performance-trap\/","title":{"rendered":"MATLAB Quirks: cellfun() high-performance trap"},"content":{"rendered":"<p>cellfun() is a powerful function in MATLAB which mirrors the idea of applying a &#8216;map&#8217; operation (as in functional programming).<\/p>\n<p>One common use is to identify which cells are empty so you can ignore them. Typically, you can do<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"matlab\">index.emptyCells = cellfun(@isempty, C);<\/pre>\n<p>According to the help (H1) page,\u00a0there is a limited set of strings that you can use in place of the function handle (functor) for backward compatibility:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"matlab\"> \nA = CELLFUN('fun', C), where 'fun' is one of the following strings,\nreturns a logical or double array A the elements of which are computed \nfrom those of C as follows:\n \n   'isreal'     -- true for cells containing a real array, false\n                   otherwise \n   'isempty'    -- true for cells containing an empty array, false \n                   otherwise \n   'islogical'  -- true for cells containing a logical array, false \n                   otherwise \n   'length'     -- the length of the contents of each cell \n   'ndims'      -- the number of dimensions of the contents of each cell\n   'prodofsize' -- the number of elements of the contents of each cell\n \nA = CELLFUN('size', C, K) returns the size along the K-th dimension of\nthe contents of each cell of C.\n \nA = CELLFUN('isclass', C, CLASSNAME) returns true for each cell of C\nthat contains an array of class CLASSNAME.  Unlike the ISA function, \n'isclass' of a subclass of CLASSNAME returns false.<\/pre>\n<p>Turns out these functions have their native implementation and runs super-fast. But I got burned once when I tried to use this on cells containing table() objects:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"matlab\">index.emptyCells = cellfun('isempty', cellsOfTables);<\/pre>\n<p>I meant to find out if I have zero-row or zero-column (empty) table objects with that. It gave\u00a0me all false even when my cells have these 0-by-0 tables. What a Terrible Failure?! Turns out these &#8216;backward compatibility&#8217; native\u00a0implementations (I guess they already have cellfun() before having function handles) looks at the raw data stream like PODs (Plain Old Datatypes) as a C program would do.<\/p>\n<p>A table() object has lots of stuff stored in it like variable (column) names, so there&#8217;s no way a program looking at an arbitrary\u00a0binary stream without accounting for such data type will consider that object\u00a0empty. It&#8217;s up to the overloaded isempty() or numel() of the class to tell what is empty and what&#8217;s not, but it needs to be called by the function handle to establish which method to call.<\/p>\n<p>Lesson learned: don&#8217;t use those\u00a0special string based functor in cellfun() unless you know for sure it&#8217;s a POD. Otherwise it will get you the wrong answer at the speed of light.<\/p>\n<div class=\"pvc_clear\"><\/div>\n<p id=\"pvc_stats_26\" class=\"pvc_stats all  \" data-element-id=\"26\" style=\"\"><i class=\"pvc-stats-icon medium\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" data-prefix=\"far\" data-icon=\"chart-bar\" role=\"img\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 512 512\" class=\"svg-inline--fa fa-chart-bar fa-w-16 fa-2x\"><path fill=\"currentColor\" d=\"M396.8 352h22.4c6.4 0 12.8-6.4 12.8-12.8V108.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v230.4c0 6.4 6.4 12.8 12.8 12.8zm-192 0h22.4c6.4 0 12.8-6.4 12.8-12.8V140.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v198.4c0 6.4 6.4 12.8 12.8 12.8zm96 0h22.4c6.4 0 12.8-6.4 12.8-12.8V204.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v134.4c0 6.4 6.4 12.8 12.8 12.8zM496 400H48V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v336c0 17.67 14.33 32 32 32h464c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16zm-387.2-48h22.4c6.4 0 12.8-6.4 12.8-12.8v-70.4c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v70.4c0 6.4 6.4 12.8 12.8 12.8z\" class=\"\"><\/path><\/svg><\/i> <img loading=\"lazy\" decoding=\"async\" width=\"16\" height=\"16\" alt=\"Loading\" src=\"https:\/\/wonghoi.humgar.com\/blog\/wp-content\/plugins\/page-views-count\/ajax-loader-2x.gif\" border=0 \/><\/p>\n<div class=\"pvc_clear\"><\/div>\n","protected":false},"excerpt":{"rendered":"<p>cellfun() is a powerful function in MATLAB which mirrors the idea of applying a &#8216;map&#8217; operation (as in functional programming). One common use is to identify which cells are empty so you can ignore them. Typically, you can do index.emptyCells &hellip; <a href=\"https:\/\/wonghoi.humgar.com\/blog\/2016\/07\/23\/matlabs-cellfun-high-performance-trap\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n<div class=\"pvc_clear\"><\/div>\n<p id=\"pvc_stats_26\" class=\"pvc_stats all  \" data-element-id=\"26\" style=\"\"><i class=\"pvc-stats-icon medium\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" data-prefix=\"far\" data-icon=\"chart-bar\" role=\"img\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 512 512\" class=\"svg-inline--fa fa-chart-bar fa-w-16 fa-2x\"><path fill=\"currentColor\" d=\"M396.8 352h22.4c6.4 0 12.8-6.4 12.8-12.8V108.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v230.4c0 6.4 6.4 12.8 12.8 12.8zm-192 0h22.4c6.4 0 12.8-6.4 12.8-12.8V140.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v198.4c0 6.4 6.4 12.8 12.8 12.8zm96 0h22.4c6.4 0 12.8-6.4 12.8-12.8V204.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v134.4c0 6.4 6.4 12.8 12.8 12.8zM496 400H48V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v336c0 17.67 14.33 32 32 32h464c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16zm-387.2-48h22.4c6.4 0 12.8-6.4 12.8-12.8v-70.4c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v70.4c0 6.4 6.4 12.8 12.8 12.8z\" class=\"\"><\/path><\/svg><\/i> <img loading=\"lazy\" decoding=\"async\" width=\"16\" height=\"16\" alt=\"Loading\" src=\"https:\/\/wonghoi.humgar.com\/blog\/wp-content\/plugins\/page-views-count\/ajax-loader-2x.gif\" border=0 \/><\/p>\n<div class=\"pvc_clear\"><\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[10,6],"tags":[],"class_list":["post-26","post","type-post","status-publish","format-standard","hentry","category-matlab","category-note-to-self"],"_links":{"self":[{"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/posts\/26","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/comments?post=26"}],"version-history":[{"count":4,"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/posts\/26\/revisions"}],"predecessor-version":[{"id":6826,"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/posts\/26\/revisions\/6826"}],"wp:attachment":[{"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/media?parent=26"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/categories?post=26"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/tags?post=26"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}