<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Low risk of breaking in future versions &#8211; Undocumented Matlab</title>
	<atom:link href="https://undocumentedmatlab.com/articles/category/presumed-future-risk/low-risk-of-breaking-in-future-versions/feed" rel="self" type="application/rss+xml" />
	<link>https://undocumentedmatlab.com</link>
	<description>Professional Matlab consulting, development and training</description>
	<lastBuildDate>Mon, 17 Aug 2020 08:29:00 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.7.2</generator>
	<item>
		<title>Speeding-up builtin Matlab functions – part 3</title>
		<link>https://undocumentedmatlab.com/articles/speeding-up-builtin-matlab-functions-part-3?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=speeding-up-builtin-matlab-functions-part-3</link>
					<comments>https://undocumentedmatlab.com/articles/speeding-up-builtin-matlab-functions-part-3#comments</comments>
		
		<dc:creator><![CDATA[Yair Altman]]></dc:creator>
		<pubDate>Mon, 06 Apr 2020 20:44:07 +0000</pubDate>
				<category><![CDATA[Low risk of breaking in future versions]]></category>
		<category><![CDATA[Stock Matlab function]]></category>
		<category><![CDATA[Toolbox]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Pure Matlab]]></category>
		<guid isPermaLink="false">http://undocumentedmatlab.com/?p=11059</guid>

					<description><![CDATA[<p>Built-in Matlab functions can often be profiled and optimized for improved run-time performance. This article shows a typical example.  </p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/speeding-up-builtin-matlab-functions-part-3">Speeding-up builtin Matlab functions – part 3</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/speeding-up-builtin-matlab-functions-part-2" rel="bookmark" title="Speeding-up builtin Matlab functions &#8211; part 2">Speeding-up builtin Matlab functions &#8211; part 2 </a> <small>Built-in Matlab functions can often be profiled and optimized for improved run-time performance. This article shows a typical example. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/speeding-up-builtin-matlab-functions-part-1" rel="bookmark" title="Speeding-up builtin Matlab functions &#8211; part 1">Speeding-up builtin Matlab functions &#8211; part 1 </a> <small>Built-in Matlab functions can often be profiled and optimized for improved run-time performance. This article shows a typical example. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/speeding-up-matlab-jdbc-sql-queries" rel="bookmark" title="Speeding up Matlab-JDBC SQL queries">Speeding up Matlab-JDBC SQL queries </a> <small>Fetching SQL ResultSet data from JDBC into Matlab can be made significantly faster. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/callback-functions-performance" rel="bookmark" title="Callback functions performance">Callback functions performance </a> <small>Using anonymous functions in Matlab callbacks can be very painful for performance. Today's article explains how this can be avoided. ...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<p>A recurring theme in this website is that despite a common misperception, builtin Matlab functions are typically coded for maximal accuracy and correctness, but not necessarily best run-time performance. Despite this, we can often identify and fix the hotspots in these functions and use a modified faster variant in our code. I have shown multiple examples for this in various posts (<a href="https://undocumentedmatlab.com/articles/speeding-up-builtin-matlab-functions-part-1" target="_blank">example1</a>, <a href="https://undocumentedmatlab.com/articles/speeding-up-builtin-matlab-functions-part-2" target="_blank">example2</a>, <a href="https://undocumentedmatlab.com/articles/tag/performance" target="_blank">many others</a>). </p>
<p>Today I will show another example, this time speeding up the <i><b>mvksdensity</b></i> (multi-variate kernel probability density estimate) function, part of the Statistics toolbox since R2016a. You will need Matlab R2016a or newer with the Stats Toolbox to recreate my results, but the general methodology and conclusions hold well for numerous other builtin Matlab functions that may be slowing down your Matlab program. In my specific problem, this function was used to compute the probability density-function (PDF) over a 1024&#215;1024 data mesh. </p>
<p>The builtin <i><b>mvksdensity</b></i> function took <b>76 seconds</b> to run on my machine; I got this down to <b>13 seconds</b>, a <b>6x speedup</b>, without compromising accuracy. Here&#8217;s how I did this:</p>
<h3 id="preparation">Preparing the work files</h3>
<p>While we could in theory modify Matlab&#8217;s installed m-files if we have administrator privileges, doing this is not a good idea for several reasons. Instead, we should copy and rename the relevant internal files to our work folder, and only modify our local copies.</p>
<p>To see where the builtin files are located, we can use the <b><i>which</i></b> function:</p>
<pre lang="matlab">
>> which('mvksdensity')
C:\Program Files\Matlab\R2020a\toolbox\stats\stats\mvksdensity.m
</pre>
<p>In our case, we copy <i>\toolbox\stats\stats\mvksdensity.m</i> as <i>mvksdensity_.m</i> to our work folder, replace the function name at the top of the file from <code>mvksdensity</code> to <code>mvksdensity_</code>, and modify our code to call <i><b>mvksdensity_</b></i> rather than <i><b>mvksdensity</b></i>. </p>
<p>If we run our code, we get an error telling us that Matlab can&#8217;t find the <i><b>statkscompute</b></i> function (in line #107 of our <i>mvksdensity_.m</i>). So we find <i>statkscompute.m</i> in the <i>\toolbox\stats\stats\private\</i> folder, copy it as <i>statkscompute_.m</i> to our work folder, rename its function name (at the top of the file) to <code>statkscompute_</code>, and modify our <i>mvksdensity_.m</i> to call <i><b>statkscompute_</b></i> rather than <i><b>statkscompute</b></i>:</p>
<pre lang="matlab">[fout,xout,u] = statkscompute_(ftype,xi,xispecified,npoints,u,L,U,weight,cutoff,...</pre>
<p>We now repeat the process over and over, until we have all copied all the necessary internal files for the program to run. In our case, it tuns out that in addition to <i>mvksdensity.m</i> and <i>statkscompute.m</i>, we also need to copy <i>statkskernelinfo.m</i>. </p>
<p>Finally, we check that the numeric results using the copied files are exactly the same as from the builtin method, just to be on the safe side that we have not left out some forgotten internal file.</p>
<p>Now that we have copied these 3 files, in practice all our attentions will be focused on the <i>dokernel</i> sub-function inside <i>statkscompute_.m</i>, since the profiling report (below) indicates that this is where all of the run-time is spent.</p>
<h3 id="identify">Identifying the hotspots</h3>
<p>Now we run the code through the Matlab Profiler, using the &#8220;Run and Time&#8221; button in the Matlab Editor, or <i><b>profile on/report</b></i> in the Matlab console (Command Window). The results show that 99.8% of <i><b>mvksdensity</b></i>&#8216;s time was spent in the internal <i>dokernel</i> function, 75% of which was spent in self-time (meaning code lines within <i>dokernel</i>):<br />
<center><figure style="width: 640px" class="wp-caption aligncenter"><img fetchpriority="high" decoding="async" src="https://undocumentedmatlab.com/images/mvksdensity-profile1.png" alt="Initial profiling results - pretty slow..." title="Initial profiling results - pretty slow..." width="640" height="280" /><figcaption class="wp-caption-text">Initial profiling results - pretty slow...</figcaption></figure></center></p>
<p>Let&#8217;s drill into <i>dokernel</i> and see where the problems are:<br />
<center><figure style="width: 764px" class="wp-caption aligncenter"><img decoding="async" src="https://undocumentedmatlab.com/images/mvksdensity-profile2.png" alt="Initial dokernel profiling results" title="Initial dokernel profiling results" width="764" height="464" /><figcaption class="wp-caption-text">Initial dokernel profiling results</figcaption></figure></center></p>
<h3 id="normal">Evaluating the normal kernel distribution</h3>
<p>We can immediately see from the profiling results that a single line (#386) in <i>statkscompute_.m</i> is responsible for nearly 40% of the total run-time:</p>
<pre lang="matlab">fk = feval(kernel,z);</pre>
<p>In this case, <code>kernel</code> is a function handle to the normal-distribution function in <i>\stats\private\statkskernelinfo&gt;normal</i>, which is evaluated 1,488,094 times. Using <i><b>feval</b></i> incurs an overhead, as can be seen by the difference in run-times: line #386 takes 29.55 secs, whereas the <b><i>normal</i></b> function evaluations only take 18.53 secs. In fact, if you drill into the <b><i>normal</i></b> function in the profiling report, you&#8217;ll see that the actual code line that computes the normal distribution only takes 8-9 seconds &#8211; all the rest (~20 secs, or ~30% of the total) is totally redundant function-call overhead. Let&#8217;s try to remove this overhead by calling the <code>kernel</code> function directly:</p>
<pre lang="matlab">fk = kernel(z);</pre>
<p>Now that we have a local copy of <i>statkscompute_.m</i>, we can safely modify the <i>dokernel</i> sub-function, specifically line #386 as explained above. It turns out that just bypassing the <i><b>feval</b></i> call and using the function-handle directly does not improve the run-time (decrease the function-call overhead) significantly, at least on recent Matlab releases (it has a greater effect on old Matlab releases, but that&#8217;s a side-issue). </p>
<p>We now recognize that the program only evaluates the normal-distribution kernel, which is the default kernel. So let&#8217;s handle this special case by inlining the kernel&#8217;s one-line code (from <i>statkskernelinfo_.m</i>) directly (note how we move the condition outside of the loop, so that it doesn&#8217;t get recomputed 1 million times):</p>
<pre lang="matlab" highlight="2,31-32,34">
...
isKernelNormal = strcmp(char(kernel),'normal');  % line #357 
for i = 1:m
    Idx = true(n,1);
    cdfIdx = true(n,1);
    cdfIdx_allBelow = true(n,1);
    for j = 1:d
        dist = txi(i,j) - ty(:,j);
        currentIdx = abs(dist) <= halfwidth(j);
        Idx = currentIdx &#038; Idx; % pdf boundary
        if iscdf
            currentCdfIdx = dist >= -halfwidth(j);
            cdfIdx = currentCdfIdx & cdfIdx; %cdf boundary1, equal or below the query point in all dimension
            currentCdfIdx_below = dist - halfwidth(j) > 0;                   
            cdfIdx_allBelow = currentCdfIdx_below & cdfIdx_allBelow; %cdf boundary2, below the pdf lower boundary in all dimension
        end
    end
    if ~iscdf
        nearby = index(Idx);
    else
        nearby = index((Idx|cdfIdx)&(~cdfIdx_allBelow));
    end
    if ~isempty(nearby)
        ftemp = ones(length(nearby),1);
        for k =1:d
            z = (txi(i,k) - ty(nearby,k))./u(k);
            if reflectionPDF
                zleft  = (txi(i,k) + ty(nearby,k)-2*L(k))./u(k);
                zright = (txi(i,k) + ty(nearby,k)-2*U(k))./u(k);
                fk = kernel(z) + kernel(zleft) + kernel(zright);  % old: =feval()+...
            elseif isKernelNormal
                fk = exp(-0.5 * (z.*z)) ./ sqrt(2*pi);
            else
                fk = kernel(z);  %old: =feval(kernel,z);
            end
            if needUntransform(k)
                fk = untransform_f(fk,L(k),U(k),xi(i,k));
            end
            ftemp = ftemp.*fk;
        end
        f(i) = weight(nearby) * ftemp;
    end
    if iscdf && any(cdfIdx_allBelow)
        f(i) = f(i) + sum(weight(cdfIdx_allBelow));
    end
end
...
</pre>
<p>This reduced the kernel evaluation run-time from ~30 secs down to 8-9 secs. Not only did we remove the direct function-call overhead, but also the overheads associated with calling a sub-function in a different m-file. The total run-time is now down to <b>45-55</b> seconds (expect some fluctuations from run to run). Not a bad start.</p>
<h3 id="loop-bottom">Main loop &#8211; bottom part</h3>
<p>Now let&#8217;s take a fresh look at the profiling report, and focus separately on the bottom and top parts of the main loop, which you can see above. We start with the bottom part, since we already messed with it in our fix to the kernel evaluation:</p>
<p><center><figure style="width: 550px" class="wp-caption aligncenter"><img decoding="async" src="https://undocumentedmatlab.com/images/mvksdensity-profile3.png" alt="Profiling results for bottom part of the main loop" title="Profiling results for bottom part of the main loop" width="550" height="348" /><figcaption class="wp-caption-text">Profiling results for bottom part of the main loop</figcaption></figure></center></p>
<p>The first thing we note is that there&#8217;s an inner loop that runs d=2 times (d is set in line #127 of <i>mvksdensity_.m</i> &#8211; it is the input mesh&#8217;s dimensionality, and also the number of columns in the <code>txi</code> data matrix). We can easily vectorize this inner loop, but we take care to do this only for the special case of d==2 and when some other special conditions occur. </p>
<p>In addition, we hoist outside of the main loop anything that we can (such as the constant exponential power, and the weight multiplication when it is constant [which is typical]), so that they are only computed once instead of 1 million times:</p>
<pre lang="matlab" highlight="3-8,12-16,34-37,39,45-50">
...
isKernelNormal = strcmp(char(kernel),'normal');
anyNeedTransform = any(needUntransform);
uniqueWeights = unique(weight);
isSingleWeight = ~iscdf && numel(uniqueWeights)==1;
isSpecialCase1 = isKernelNormal && ~reflectionPDF && ~anyNeedTransform && d==2;
expFactor = -0.5 ./ (u.*u)';
TWO_PI = 2*pi;
for i = 1:m
    ...
    if ~isempty(nearby)
        if isSpecialCase1
            z = txi(i,:) - ty(nearby,:);
            ftemp = exp((z.*z) * expFactor);
        else
            ftemp = 1;  % no need for the slow ones()
            for k = 1:d
                z = (txi(i,k) - ty(nearby,k)) ./ u(k);
                if reflectionPDF
                    zleft  = (txi(i,k) + ty(nearby,k)-2*L(k)) ./ u(k);
                    zright = (txi(i,k) + ty(nearby,k)-2*U(k)) ./ u(k);
                    fk = kernel(z) + kernel(zleft) + kernel(zright);  % old: =feval()+...
                elseif isKernelNormal
                    fk = exp(-0.5 * (z.*z)) ./ sqrt(TWO_PI);
                else
                    fk = kernel(z);  % old: =feval(kernel,z)
                end
                if needUntransform(k)
                    fk = untransform_f(fk,L(k),U(k),xi(i,k));
                end
                ftemp = ftemp.*fk;
            end
            ftemp = ftemp * TWO_PI;
        end
        if isSingleWeight
            f(i) = sum(ftemp);
        else
            f(i) = weight(nearby) * ftemp;
        end
    end
    if iscdf && any(cdfIdx_allBelow)
        f(i) = f(i) + sum(weight(cdfIdx_allBelow));
    end
end
if isSingleWeight
    f = f * uniqueWeights;
end
if isKernelNormal && ~reflectionPDF
    f = f ./ TWO_PI;
end
...
</pre>
<p>This brings the run-time down to <b>31-32 secs</b>. Not bad at all, but we can still do much better:</p>
<h3 id="loop-top">Main loop &#8211; top part</h3>
<p>Now let&#8217;s take a look at the profiling report&#8217;s top part of the main loop:</p>
<p><center><figure style="width: 550px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" src="https://undocumentedmatlab.com/images/mvksdensity-profile4.png" alt="Profiling results for top part of the main loop" title="Profiling results for to part of the main loop" width="550" height="414" /><figcaption class="wp-caption-text">Profiling results for top part of the main loop</figcaption></figure></center></p>
<p>Again we note is that there&#8217;s an inner loop that runs d=2 times, which we can again easily vectorize. In addition, we note the unnecessary repeated initializations of the <code>true(n,1)</code> vector, which can easily be hoisted outside the loop:</p>
<pre lang="matlab" highlight="2-3,5-13,30">
...
TRUE_N = true(n,1);
isSpecialCase2 = ~iscdf && d==2;
for i = 1:m
    if isSpecialCase2
        dist = txi(i,:) - ty;
        currentIdx = abs(dist) <= halfwidth;
        currentIdx = currentIdx(:,1) &#038; currentIdx(:,2);
        nearby = index(currentIdx);
    else
        Idx = TRUE_N;
        cdfIdx = TRUE_N;
        cdfIdx_allBelow = TRUE_N;
        for j = 1:d
            dist = txi(i,j) - ty(:,j);
            currentIdx = abs(dist) <= halfwidth(j);
            Idx = currentIdx &#038; Idx; % pdf boundary
            if iscdf
                currentCdfIdx = dist >= -halfwidth(j);
                cdfIdx = currentCdfIdx & cdfIdx; % cdf boundary1, equal or below the query point in all dimension
                currentCdfIdx_below = dist - halfwidth(j) > 0;
                cdfIdx_allBelow = currentCdfIdx_below & cdfIdx_allBelow; %cdf boundary2, below the pdf lower boundary in all dimension
            end
        end
        if ~iscdf
            nearby = index(Idx);
        else
            nearby = index((Idx|cdfIdx)&(~cdfIdx_allBelow));
        end
    end
    if ~isempty(nearby)
        ...
</pre>
<p>This brings the run-time down to <b>24 seconds</b>. </p>
<p>We next note that instead of using numeric indexes to compute the <code>nearby</code> vector, we could use faster logical indexes:</p>
<pre lang="matlab" highlight="2,9,26,28,31">
...
%index = (1:n)';  % this is no longer needed
TRUE_N = true(n,1);
isSpecialCase2 = ~iscdf && d==2;
for i = 1:m
    if isSpecialCase2
        dist = txi(i,:) - ty;
        currentIdx = abs(dist) <= halfwidth;
        nearby = currentIdx(:,1) &#038; currentIdx(:,2);
    else
        Idx = TRUE_N;
        cdfIdx = TRUE_N;
        cdfIdx_allBelow = TRUE_N;
        for j = 1:d
            dist = txi(i,j) - ty(:,j);
            currentIdx = abs(dist) <= halfwidth(j);
            Idx = currentIdx &#038; Idx; % pdf boundary
            if iscdf
                currentCdfIdx = dist >= -halfwidth(j);
                cdfIdx = currentCdfIdx & cdfIdx; % cdf boundary1, equal or below the query point in all dimension
                currentCdfIdx_below = dist - halfwidth(j) > 0;
                cdfIdx_allBelow = currentCdfIdx_below & cdfIdx_allBelow; %cdf boundary2, below the pdf lower boundary in all dimension
            end
        end
        if ~iscdf
            nearby = Idx;  % not index(Idx)
        else
            nearby = (Idx|cdfIdx) & ~cdfIdx_allBelow;  % no index()
        end
    end
    if any(nearby)
        ...
</pre>
<p>This brings the run-time down to <b>20 seconds</b>. </p>
<p>We now note that the main loop runs m=1,048,576 (=1024&#215;1024) times over all rows of <code>txi</code>. This is expected, since the loop runs over all the elements of a 1024&#215;1024 mesh grid, which are reshaped as a 1,048,576-element column array at some earlier point in the processing, resulting in a m-by-d matrix (1,048,576-by-2 in our specific case). This information helps us, because we know that there are only 1024 unique values in each of the two columns of <code>txi</code>. Therefore, instead of computing the &#8220;closeness&#8221; metric (which leads to the <code>nearby</code> vector) for all 1,048,576 x 2 values of <code>txi</code>, we calculate separate vectors for each of the 1024 unique values in each of its 2 columns, and then merge the results inside the loop:</p>
<pre lang="matlab" highlight="3-10,13-15">
...
isSpecialCase2 = ~iscdf && d==2;
if isSpecialCase2
    [unique1Vals, ~, unique1Idx] = unique(txi(:,1));
    [unique2Vals, ~, unique2Idx] = unique(txi(:,2));
    dist1 = unique1Vals' - ty(:,1);
    dist2 = unique2Vals' - ty(:,2);
    currentIdx1 = abs(dist1) <= halfwidth(1);
    currentIdx2 = abs(dist2) <= halfwidth(2);
end
for i = 1:m
    if isSpecialCase2
        idx1 = unique1Idx(i);
        idx2 = unique2Idx(i);
        nearby = currentIdx1(:,idx1) &#038; currentIdx2(:,idx2);
    else
        ...
</pre>
<p>This brings the run-time down to <b>13 seconds</b>, a total speedup of almost ~6x compared to the original version. Not bad at all.</p>
<p>For reference, here's a profiling summary of the <i>dokernel</i> function again, showing the updated performance hotspots:</p>
<p><center><figure style="width: 550px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" src="https://undocumentedmatlab.com/images/mvksdensity-profile5.png" alt="Profiling results after optimization" title="Profiling results after optimization" width="550" height="201" /><figcaption class="wp-caption-text">Profiling results after optimization</figcaption></figure></center></p>
<p>The 2 vectorized code lines in the bottom part of the main loop now account for 72% of the remaining run-time:</p>
<pre lang="matlab" highlight="4-5">
    ...
    if ~isempty(nearby)
        if isSpecialCase1
            z = txi(i,:) - ty(nearby,:);
            ftemp = exp((z.*z) * expFactor);
        else
            ...
</pre>
<p>If I had the inclination, speeding up these two code lines would be the next logical step, but I stop at this point. Interested readers could pick up this challenge and post a solution in the comments section below. I haven't tried it myself, so perhaps there's no easy way to improve this. Then again, perhaps the answer is just around the corner - if you don't try, you'll never know...</p>
<h3 id="resolution">Data density/resolution</h3>
<p>So far, all the optimization I made have not affected code accuracy, generality or resolution. This is always the best approach if you have some spare coding time on your hands.</p>
<p>In some cases, we might have a deep understanding of our domain problem to be able to sacrifice a bit of accuracy in return for run-time speedup. In our case, we identify the main loop over 1024x1024 elements as the deciding factor in the run-time. If we reduce the grid-size by 50% in each dimension (i.e. 512x512), the run-time decreases by an additional factor of almost 4, down to <b>~3.5 seconds</b>, which is what we would have expected since the main loop size has decreased 4 times in size. While this reduces the results resolution/accuracy, we got a 4x speedup in a fraction of the time that it took to make all the coding changes above. </p>
<p>Different situations may require different approaches: in some cases we cannot sacrifice accuracy/resolution, and must spend time to improve the algorithm implementation; in other cases coding time is at a premium and we can sacrifice accuracy/resolution; and in other cases still, we could use a combination of both approaches.</p>
<h3 id="conclusions">Conclusions</h3>
<p>Matlab is composed of thousands of internal functions. Each and every one of these functions was meticulously developed and tested by engineers, who are after all only human. Whereas supreme emphasis is always placed with Matlab functions on their accuracy, run-time performance often takes a back-seat. Make no mistake about this: code accuracy is almost always more important than speed, so I’m not complaining about the current state of affairs.</p>
<p>But when we run into a specific run-time problem in our Matlab program, we should not despair if we see that built-in functions cause slowdown. We can try to avoid calling those functions (for example, by reducing the number of invocations, or decreasing the data resolution, or limiting the target accuracy, etc.), or we could optimize these functions in our own local copy, as I have shown today. There are multiple techniques that we could employ to improve the run time. Just use the profiler and keep an open mind about alternative speed-up mechanisms, and you’d be half-way there. For ideas about the multitude of different speedup techniques that you could use in Matlab, see my book <b><a href="https://undocumentedmatlab.com/books/matlab-performance" target="_blank">Accelerating Matlab Performance</a></b>.</p>
<p><a href="https://undocumentedmatlab.com/consulting" target="_blank">Let me know</a> if you’d like me to assist with your Matlab project, either developing it from scratch or improving your existing code, or just training you in how to improve your Matlab code’s run-time/robustness/usability/appearance.</p>
<p>In the meantime, Happy Easter/Passover everyone, and stay healthy!</p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/speeding-up-builtin-matlab-functions-part-3">Speeding-up builtin Matlab functions – part 3</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/speeding-up-builtin-matlab-functions-part-2" rel="bookmark" title="Speeding-up builtin Matlab functions &#8211; part 2">Speeding-up builtin Matlab functions &#8211; part 2 </a> <small>Built-in Matlab functions can often be profiled and optimized for improved run-time performance. This article shows a typical example. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/speeding-up-builtin-matlab-functions-part-1" rel="bookmark" title="Speeding-up builtin Matlab functions &#8211; part 1">Speeding-up builtin Matlab functions &#8211; part 1 </a> <small>Built-in Matlab functions can often be profiled and optimized for improved run-time performance. This article shows a typical example. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/speeding-up-matlab-jdbc-sql-queries" rel="bookmark" title="Speeding up Matlab-JDBC SQL queries">Speeding up Matlab-JDBC SQL queries </a> <small>Fetching SQL ResultSet data from JDBC into Matlab can be made significantly faster. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/callback-functions-performance" rel="bookmark" title="Callback functions performance">Callback functions performance </a> <small>Using anonymous functions in Matlab callbacks can be very painful for performance. Today's article explains how this can be avoided. ...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://undocumentedmatlab.com/articles/speeding-up-builtin-matlab-functions-part-3/feed</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>Undocumented plot marker types</title>
		<link>https://undocumentedmatlab.com/articles/undocumented-plot-marker-types?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=undocumented-plot-marker-types</link>
					<comments>https://undocumentedmatlab.com/articles/undocumented-plot-marker-types#comments</comments>
		
		<dc:creator><![CDATA[Yair Altman]]></dc:creator>
		<pubDate>Wed, 13 Mar 2019 11:05:14 +0000</pubDate>
				<category><![CDATA[Handle graphics]]></category>
		<category><![CDATA[Hidden property]]></category>
		<category><![CDATA[Low risk of breaking in future versions]]></category>
		<category><![CDATA[Stock Matlab function]]></category>
		<category><![CDATA[Undocumented feature]]></category>
		<category><![CDATA[HG2]]></category>
		<category><![CDATA[Internal component]]></category>
		<category><![CDATA[Pure Matlab]]></category>
		<guid isPermaLink="false">http://undocumentedmatlab.com/?p=8539</guid>

					<description><![CDATA[<p>Undocumented plot marker styles can easily be accesses using a hidden plot-line property. </p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/undocumented-plot-marker-types">Undocumented plot marker types</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/types-of-undocumented-matlab-aspects" rel="bookmark" title="Types of undocumented Matlab aspects">Types of undocumented Matlab aspects </a> <small>This article lists the different types of undocumented/unsupported/hidden aspects in Matlab...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/undocumented-scatter-plot-behavior" rel="bookmark" title="Undocumented scatter plot behavior">Undocumented scatter plot behavior </a> <small>The scatter plot function has an undocumented behavior when plotting more than 100 points: it returns a single unified patch object handle, rather than a patch handle for each specific point as it returns with 100 or less points....</small></li>
<li><a href="https://undocumentedmatlab.com/articles/plot-markers-transparency-and-color-gradient" rel="bookmark" title="Plot markers transparency and color gradient">Plot markers transparency and color gradient </a> <small>Matlab plot-line markers can be customized to have transparency and color gradients. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/undocumented-scatter-plot-jitter" rel="bookmark" title="Undocumented scatter plot jitter">Undocumented scatter plot jitter </a> <small>Matlab's scatter plot can automatically jitter data to enable better visualization of distribution density. ...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<p>I wanted to take a break from my miniseries on the Matlab toolstrip to describe a nice little undocumented aspect of plot line markers. Plot line marker types have remained essentially unchanged in user-facing functionality for the past two+ decades, allowing the well-known marker types (.,+,o,^ etc.). Internally, lots of things changed in the graphics engine, particularly in the <a href="https://undocumentedmatlab.com/articles/hg2-update" target="_blank">transition to HG2</a> in R2014b and the <a href="https://blogs.mathworks.com/graphics/2015/11/10/memory-consumption/#comment-465" rel="nofollow" target="_blank">implementation of markers using OpenGL primitives</a>. I suspect that during the massive amount of development work that was done at that time, important functionality improvements that were implemented in the engine were forgotten and did not percolate all the way up to the user-facing functions. I highlighted a few of these in the past, for example transparency and color gradient for <a href="https://undocumentedmatlab.com/articles/plot-line-transparency-and-color-gradient" target="_blank">plot lines</a> and <a href="https://undocumentedmatlab.com/articles/plot-markers-transparency-and-color-gradient" target="_blank">markers</a>, or <a href="https://undocumentedmatlab.com/articles/hidden-hg2-plot-functionality" target="_blank">various aspects of contour plots</a>.<br />
Fortunately, Matlab usually exposes the internal objects that we can customize and which enable these extra features, in hidden properties of the top-level graphics handle. For example, the standard Matlab plot-line handle has a hidden property called <b>MarkerHandle</b> that we can access. This returns an internal object that enables <a href="https://undocumentedmatlab.com/articles/plot-markers-transparency-and-color-gradient" target="_blank">marker transparency and color gradients</a>. We can also use this object to set the marker style to a couple of formats that are not available in the top-level object:</p>
<pre lang="matlab">
>> x=1:10; y=10*x; hLine=plot(x,y,'o-'); box off; drawnow;
>> hLine.MarkerEdgeColor = 'r';
>> set(hLine, 'Marker')'  % top-level marker styles
ans =
  1×14 cell array
    {'+'} {'o'} {'*'} {'.'} {'x'} {'square'} {'diamond'} {'v'} {'^'} {'>'} {'<'} {'pentagram'} {'hexagram'} {'none'}
>> set(hLine.MarkerHandle, 'Style')'  % low-level marker styles
ans =
  1×16 cell array
    {'plus'} {'circle'} {'asterisk'} {'point'} {'x'} {'square'} {'diamond'} {'downtriangle'} {'triangle'} {'righttriangle'} {'lefttriangle'} {'pentagram'} {'hexagram'} {'vbar'} {'hbar'} {'none'}
</pre>
<p>We see that the top-level marker styles directly correspond to the low-level styles, except for the low-level &#8216;vbar&#8217; and &#8216;hbar&#8217; styles. Perhaps the developers forgot to add these two styles to the top-level object in the enormous upheaval of HG2. Luckily, we can set the hbar/vbar styles directly, using the line&#8217;s <b>MarkerHandle</b> property:</p>
<pre lang="matlab">
hLine.MarkerHandle.Style = 'hbar';
set(hLine.MarkerHandle, 'Style','hbar');  % alternative
</pre>
<p><center><figure style="width: 213px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" src="https://undocumentedmatlab.com/images/plot_hbar.png" alt="hLine.MarkerHandle.Style='hbar'" title="hLine.MarkerHandle.Style='hbar'" width="213" height="155" /><figcaption class="wp-caption-text">hLine.MarkerHandle.Style='hbar'</figcaption></figure> <figure style="width: 213px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" src="https://undocumentedmatlab.com/images/plot_vbar.png" alt="hLine.MarkerHandle.Style='vbar'" title="hLine.MarkerHandle.Style='vbar'" width="213" height="155" /><figcaption class="wp-caption-text">hLine.MarkerHandle.Style='vbar'</figcaption></figure></center></p>
<h3 id="USA">USA visit</h3>
<p>I will be travelling in the US in May/June 2019. Please let me know (altmany at gmail) if you would like to schedule a meeting or onsite visit for consulting/training, or perhaps just to explore the possibility of my professional assistance to your Matlab programming needs.</p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/undocumented-plot-marker-types">Undocumented plot marker types</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/types-of-undocumented-matlab-aspects" rel="bookmark" title="Types of undocumented Matlab aspects">Types of undocumented Matlab aspects </a> <small>This article lists the different types of undocumented/unsupported/hidden aspects in Matlab...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/undocumented-scatter-plot-behavior" rel="bookmark" title="Undocumented scatter plot behavior">Undocumented scatter plot behavior </a> <small>The scatter plot function has an undocumented behavior when plotting more than 100 points: it returns a single unified patch object handle, rather than a patch handle for each specific point as it returns with 100 or less points....</small></li>
<li><a href="https://undocumentedmatlab.com/articles/plot-markers-transparency-and-color-gradient" rel="bookmark" title="Plot markers transparency and color gradient">Plot markers transparency and color gradient </a> <small>Matlab plot-line markers can be customized to have transparency and color gradients. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/undocumented-scatter-plot-jitter" rel="bookmark" title="Undocumented scatter plot jitter">Undocumented scatter plot jitter </a> <small>Matlab's scatter plot can automatically jitter data to enable better visualization of distribution density. ...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://undocumentedmatlab.com/articles/undocumented-plot-marker-types/feed</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Multi-threaded Mex</title>
		<link>https://undocumentedmatlab.com/articles/multi-threaded-mex?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=multi-threaded-mex</link>
					<comments>https://undocumentedmatlab.com/articles/multi-threaded-mex#comments</comments>
		
		<dc:creator><![CDATA[Yair Altman]]></dc:creator>
		<pubDate>Wed, 18 Jul 2018 14:56:44 +0000</pubDate>
				<category><![CDATA[Low risk of breaking in future versions]]></category>
		<category><![CDATA[Mex]]></category>
		<category><![CDATA[Undocumented feature]]></category>
		<category><![CDATA[Performance]]></category>
		<guid isPermaLink="false">http://undocumentedmatlab.com/?p=7771</guid>

					<description><![CDATA[<p>Tips for creating and debugging multi-threaded Mex functions are discussed. </p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/multi-threaded-mex">Multi-threaded Mex</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/explicit-multi-threading-in-matlab-part4" rel="bookmark" title="Explicit multi-threading in Matlab part 4">Explicit multi-threading in Matlab part 4 </a> <small>Matlab performance can be improved by employing timer objects and spawning external processes. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/explicit-multi-threading-in-matlab-part3" rel="bookmark" title="Explicit multi-threading in Matlab part 3">Explicit multi-threading in Matlab part 3 </a> <small>Matlab performance can be improved by employing POSIX threads in C/C++ code. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/explicit-multi-threading-in-matlab-part2" rel="bookmark" title="Explicit multi-threading in Matlab part 2">Explicit multi-threading in Matlab part 2 </a> <small>Matlab performance can be improved by employing .Net (C#, VB, F# or C++) threads. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/multi-line-uitable-column-headers" rel="bookmark" title="Multi-line uitable column headers">Multi-line uitable column headers </a> <small>Matlab uitables can present long column headers in multiple lines, for improved readability. ...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<p>I was recently asked by a consulting client to help speed up a Matlab process. <span class="alignright"><img loading="lazy" decoding="async" src="https://undocumentedmatlab.com/images/speedometer4d_200x200.gif" alt="Accelerating MATLAB Performance" title="Accelerating MATLAB Performance" width="200" height="200" /></span> Quite often there are various ways to improve the run-time, and in this particular case it turned out that the best option was to convert the core Matlab processing loop into a multi-threaded Mex function, while keeping the rest (vast majority of program code) in easy-to-maintain Matlab. This resulted in a 160x speedup (25 secs => 0.16 secs). Some of this speedup is attributed to C-code being faster in general than Matlab, another part is due to the multi-threading, and another due to <a href="/articles/matlab-mex-in-place-editing" target="_blank">in-place data manipulations</a> that avoid costly memory access and re-allocations.<br />
In today&#8217;s post I will share some of the insights relating to this MEX conversion, which could be adapted for many other similar use-cases. Additional Matlab speed-up techniques can be found in other <a href="/articles/tag/performance" target="_blank">performance-related posts</a> on this website, as well in my book <a href="/books/matlab-performance" target="_blank"><b>Accelerating MATLAB Performance</b></a>.<br />
There are quite a few online resources about creating Mex files, so I will not focus on this aspect. I&#8217;ll assume that the reader is already familiar with the concept of using Mex functions, which are simply dynamically-linked libraries that have a predefined entry-function syntax and predefined platform-specific extension. Instead, I&#8217;ll focus on how to create and debug a multi-threaded Mex function, so that it runs in parallel on all CPU cores.<br />
The benefit of multi-<i>threading</i> is that threads are very light-weight objects, that have minimal performance and memory overheads. This contrasts to multi-<i>tasking</i>, which is what the Parallel Computing Toolbox currently does: launches duplicate copies of the entire Matlab engine process (&#8220;headless workers&#8221;) and then manages and coordinates the tasks to split up the processing work. Multi-tasking should be avoided wherever we can employ light-weight multi-threading instead. Unfortunately, Matlab does not currently have the ability to explicitly multi-thread Matlab code. But we can still use explicit multi-threading by invoking code in other languages, as I&#8217;ve already shown for <a href="/articles/explicit-multi-threading-in-matlab-part1" target="_blank">Java</a>, <a href="/articles/explicit-multi-threading-in-matlab-part2" target="_blank">C# (and .NET in general)</a>, and <a href="/articles/explicit-multi-threading-in-matlab-part3" target="_blank">C/C++</a>. Today&#8217;s article will expand on the latter post (the one about C/C++ multi-threading), by showing a general framework for making a multi-threaded C-based Mex function.<br />
<span id="more-7771"></span><br />
There are several alternative implementation of threads. On non-Windows machines, POSIX threads (&#8220;pthreads&#8221;) are a de-facto standard; on Windows, which pthreads can still be used, they generally use native Windows threads under the hood, and we can use these native threads directly.<br />
I have uploaded a file called <a href="https://www.mathworks.com/matlabcentral/fileexchange/68237-max_in_place-example-of-multi-threaded-mex-function" rel="nofollow" target="_blank">max_in_place</a> to the Matlab File Exchange. This function serves as an example showing a generic multi-threaded Mex function. A compiled version of this Mex file for Win64 is also included in the File Exchange entry, and you can run it directly on a Win64 machine.<br />
The usage in Matlab is as follows (note how <code>matrix1</code> is updated in-place):</p>
<pre lang="matlab">
>> matrix1 = rand(4)
matrix1 =
      0.89092      0.14929      0.81428      0.19664
      0.95929      0.25751      0.24352      0.25108
      0.54722      0.84072      0.92926      0.61604
      0.13862      0.25428      0.34998      0.47329
>> matrix2 = rand(4)
matrix2 =
      0.35166      0.91719      0.38045      0.53081
      0.83083      0.28584      0.56782      0.77917
      0.58526       0.7572     0.075854      0.93401
      0.54972      0.75373      0.05395      0.12991
>> max_in_place(matrix1, matrix2)
>> matrix1
matrix1 =
      0.89092      0.91719      0.81428      0.53081
      0.95929      0.28584      0.56782      0.77917
      0.58526      0.84072      0.92926      0.93401
      0.54972      0.75373      0.34998      0.47329
</pre>
<h3 id="source-code">Source code and discussion</h3>
<p>The pseudo-code for the MEX function is as follows:</p>
<pre lang="text">
mexFunction():
   validate the input/output args
   quick bail-out if empty inputs
   get the number of threads N from Matlab's maxNumCompThreads function
   if N == 1
       run main_loop directly
   else
       split input matrix #1 into N index blocks
       assign start/end index for each thread
       create and launch N new threads that run main_loop
       wait for all N threads to complete
       free the allocated memory resources
   end
</pre>
<p>Here&#8217;s the core source-code of this function, which was adapted from original work by <a href="https://www.mathworks.com/matlabcentral/profile/authors/1097878-dirk-jan-kroon" rel="nofollow" target="_blank">Dirk-Jan Kroon</a>:</p>
<pre lang="cpp">
/*====================================================================
 *
 * max_in_place.c  updates a data matrix in-place with the max value
 *                 of the matrix and a 2nd matrix of the same size
 *
 * The calling syntax is:
 *
 *		max_in_place(matrix1, matrix2)
 *
 * matrix1 will be updated with the maximal values from corresponding
 * indices of the 2 matrices
 *
 * Both inputs must be double 2D real non-sparse matrices of same size
 *
 * Yair Altman 2018-07-18
 * https://UndocumentedMatlab.com/articles/multi-threaded-mex
 *
 * Adapted from original work by Dirk-Jan Kroon
 * http://mathworks.com/matlabcentral/profile/authors/1097878-dirk-jan-kroon
 *
 *==================================================================*/
#include <math.h>
#include "mex.h"
/* undef needed for LCC compiler */
#undef EXTERN_C
#ifdef _WIN32
    #include <windows.h>
    #include <process.h>
#else
    #include <pthread.h>
#endif
/* Input Arguments */
#define	hMatrix1	prhs[0]
#define	hMatrix2	prhs[1]
/* Macros */
#if !defined(MAX)
#define	MIN(A, B)	((A) < (B) ? (A) : (B))
#endif
/* Main processing loop function */
void main_loop(const mxArray *prhs[], int startIdx, int endIdx)
{
    /* Assign pointers to the various parameters */
    double *p1 = mxGetPr(hMatrix1);
    double *p2 = mxGetPr(hMatrix2);
    /* Loop through all matrix coordinates */
    for (int idx=startIdx; idx<=endIdx; idx++)
    {
        /* Update hMatrix1 with the maximal value of hMatrix1,hMatrix2 */
        if (p1[idx] < p2[idx]) {
            p1[idx] = p2[idx];
        }
    }
}
/* Computation function in threads */
#ifdef _WIN32
  unsigned __stdcall thread_func(void *ThreadArgs_) {
#else
  void thread_func(void *ThreadArgs_) {
#endif
    double **ThreadArgs = ThreadArgs_;  /* void* => double** */
    const mxArray** prhs = (const mxArray**) ThreadArgs[0];
    int ThreadID = (int) ThreadArgs[1][0];
    int startIdx = (int) ThreadArgs[2][0];
    int endIdx   = (int) ThreadArgs[3][0];
    /*mexPrintf("Starting thread #%d: idx=%d:%d\n", ThreadID, startIdx, endIdx); */
    /* Run the main processing function */
    main_loop(prhs, startIdx, endIdx);
    /* Explicit end thread, helps to ensure proper recovery of resources allocated for the thread */
    #ifdef _WIN32
        _endthreadex( 0 );
        return 0;
    #else
        pthread_exit(NULL);
    #endif
}
/* validateInputs function here... */
/* Main entry function */
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    /* Validate the inputs */
    validateInputs(nlhs, plhs, nrhs, prhs);
    /* Quick bail-out in the trivial case of empty inputs */
    if (mxIsEmpty(hMatrix1))  return;
    /* Get the number of threads from the Matlab engine (maxNumCompThreads) */
    mxArray *matlabCallOut[1] = {0};
    mxArray *matlabCallIn[1]  = {0};
    mexCallMATLAB(1, matlabCallOut, 0, matlabCallIn, "maxNumCompThreads");
    double *Nthreadsd = mxGetPr(matlabCallOut[0]);
    int Nthreads = (int) Nthreadsd[0];
    /* Get the number of elements to process */
    size_t n1 = mxGetNumberOfElements(hMatrix1);
    if (Nthreads == 1) {
        /* Process the inputs directly (not via a thread) */
        main_loop(prhs, 0, n1-1);
    } else {  /* multi-threaded */
        /* Allocate memory for handles of worker threads */
        #ifdef _WIN32
            HANDLE    *ThreadList = (HANDLE*)   malloc(Nthreads*sizeof(HANDLE));
        #else
            pthread_t *ThreadList = (pthread_t*)malloc(Nthreads*sizeof(pthread_t));
        #endif
        /* Allocate memory for the thread arguments (attributes) */
        double **ThreadID, **ThreadStartIdx, **ThreadEndIdx, ***ThreadArgs;
        double *ThreadID1, *ThreadStartIdx1, *ThreadEndIdx1, **ThreadArgs1;
        ThreadID       = (double **) malloc( Nthreads* sizeof(double *) );
        ThreadStartIdx = (double **) malloc( Nthreads* sizeof(double *) );
        ThreadEndIdx   = (double **) malloc( Nthreads* sizeof(double *) );
        ThreadArgs     = (double ***)malloc( Nthreads* sizeof(double **) );
        /* Launch the requested number of threads */
        int i;
        int threadBlockSize = ceil( ((double)n1) / Nthreads );
        for (i=0; i<nthreads; i++)
        {
            /* Create thread ID */
            ThreadID1 = (double *)malloc( 1* sizeof(double) );
            ThreadID1[0] = i;
            ThreadID[i] = ThreadID1;
            /* Compute start/end indexes for this thread */
            ThreadStartIdx1 = (double *) malloc( sizeof(double) );
            ThreadStartIdx1[0] = i * threadBlockSize;
            ThreadStartIdx[i] = ThreadStartIdx1;
            ThreadEndIdx1 = (double *) malloc( sizeof(double) );
            ThreadEndIdx1[0] = MIN((i+1)*threadBlockSize, n1) - 1;
            ThreadEndIdx[i] = ThreadEndIdx1;
            /* Prepare thread input args */
            ThreadArgs1 = (double **) malloc( 4* sizeof(double*) );
            ThreadArgs1[0] = (double *) prhs;
            ThreadArgs1[1] = ThreadID[i];
            ThreadArgs1[2] = ThreadStartIdx[i];
            ThreadArgs1[3] = ThreadEndIdx[i];
            ThreadArgs[i] = ThreadArgs1;
            /* Launch the thread with its associated args */
            #ifdef _WIN32
                ThreadList[i] = (HANDLE)_beginthreadex(NULL, 0, &#038;thread_func, ThreadArgs[i], 0, NULL);
            #else
                pthread_create ((pthread_t*)&#038;ThreadList[i], NULL, (void *) &#038;thread_func, ThreadArgs[i]);
            #endif
        }
        /* Wait for all the treads to finish working */
        #ifdef _WIN32
            for (i=0; i<nthreads; i++) { WaitForSingleObject(ThreadList[i], INFINITE); }
            for (i=0; i<nthreads; i++) { CloseHandle( ThreadList[i] ); }
        #else
            for (i=0; i<nthreads; i++) { pthread_join(ThreadList[i],NULL); }
        #endif
        /* Free the memory resources allocated for the threads */
        for (i=0; i<nthreads; i++)
        {
            free(ThreadArgs[i]);
            free(ThreadID[i]);
            free(ThreadStartIdx[i]);
            free(ThreadEndIdx[i]);
        }
        free(ThreadArgs);
        free(ThreadID );
        free(ThreadStartIdx);
        free(ThreadEndIdx);
        free(ThreadList);
    }
    return;
}
</pre>
<p>This file also includes a <i>validateInputs</i> function. I did not include it in the code snippet above for brevity; you can read it directly in the FEX entry (<i>max_in_place.c</i>). This function checks that there are exactly 0 output and 2 input args, that the input args are real non-sparse matrices and that they have the same number of elements.<br />
Note that the threads run a generic <i>thread_func</i> function, which in turn runs the <i>main_loop</i> function with the thread's specified <code>startIndex</code>, <code>endIndex</code> values. When this function completes, the thread ends itself explicitly, to ensure resource cleanup.<br />
Also note how the thread code is using pthreads on non-Windows (<code>!defined(_WIN32)</code>) machines, and native Windows threads otherwise. This means that the same MEX source-code could be used on all Matlab platforms.<br />
The important thing to note about this framework is that we no longer need to worry about the thread plumbing. If we wish to adapt this code for any other processing, we just need to modify the <i>main_loop</i> function with the new processing logic. In addition, you may wish to modify the <i>validateInputs</i> function based on your new setup of input/output args.<br />
A few caveats:</p>
<ul>
<li>On Windows machines with R2017b or older, we simply compile using <code>mex max_in_place.c</code>; on non-Windows we might need to add the <code>–lpthread</code> flag to link the pthreads library, depending on your specific compiler.</li>
<li>On R2018a or newer on all platforms, due to MEX's new <a href="https://www.mathworks.com/help/matlab/matlab_external/matlab-support-for-interleaved-complex.html" rel="nofollow" target="_blank">interleaved-complex memory format</a>, we would need to compile with the <code>-R2017b</code> flag if we wish to use <i><a href="https://www.mathworks.com/help/matlab/apiref/mxgetpr.html" rel="nofollow" target="_blank">mexGetPr</a></i>, as in the sample code above (in R2018a's new data model, the corresponding function is <i><a href="https://www.mathworks.com/help/matlab/apiref/mxgetdoubles.html" rel="nofollow" target="_blank">mxGetDoubles</a></i>). Note that updating data in-place becomes more difficult with the new MEX API, so if you want to preserve the performance boost that in-place data manipulation provides, it may be better to stick with the legacy data memory model.</li>
<li>The sample code above splits the data between the threads based on the first input matrix's size. Instead, you may consider sending to the MEX function the loop indexes as extra input args, and then splitting those up between the threads.</li>
<li>In this specific implementation of <i>max_in_place</i>, I have updated the data locations directly. This is generally discouraged and risky, because it conflicts with Matlab's standard Copy-on-Write mechanism. For example, if we assign the input to any other Matlab variable(s) before calling <i>max_in_place</i>, then that other variable(s) will also get their data updated. If we do not want this side-effect, we should <a href="/articles/matlab-mex-in-place-editing" target="_blank">mxUnshareArray</a> the input matrix1, and return the resulting matrix as an output of the MEX function (<code>plhs[0]</code>).</li>
</ul>
<h3 id="tips">Speed-up tips</h3>
<p>The core logic in the specific case that I was asked to optimize was something similar to this:</p>
<pre lang="text">
main_process:
    initialize output matrix
    loop z over all slices in a 3D data matrix
        temp_data = data(:,:,z);
        temp_data = process(temp_data);
        output = max(output, temp_data);
    end z loop
</pre>
<p>The initial speed-up attempt was naturally focused on the <code>process</code> and <code>max</code> functions. Converting them to a MEX function improved the speed by a factor of ~8, but the resulting run-time (4-5 secs) was still too slow for real-time use. The reason that we did not see a larger speed-up was, I believe, due to several reasons:</p>
<ul>
<li><code>temp_data</code> was small enough such that the overheads associated with creating and then disposing separate threads were significant compared to the processing time of each thread.</li>
<li><code>temp_data</code> was small enough such that each thread processed a relatively small portion of the memory, in contrast to single-threaded processing that accesses memory in larger blocks, more efficiently.</li>
<li>In each iteration of the z loop, the overheads associated with calling the MEX function, handling input variables and validation, creating/disposing threads, and allocating/deallocating memory for <code>temp_data</code>, were repeatedly paid.</li>
</ul>
<p>So, while the profiling result showed that 98% of the time was spent in the MEX function (which would seem to indicate that not much additional speedup can be achieved), in fact the MEX function was under-performing because of the inefficiencies involved in repeatedly creating threads to process small data chunks. It turned out that running in single-thread mode was actually somewhat faster than multi-threaded mode.<br />
I then moved the entire z loop (entire <code>main_process</code>) into the MEX function, where the threads were split to process separate adjacent blocks of z slices (i.e. different blocks of the z loop). This way, the MEX function was called, the inputs validated, and threads created/disposed only once for the entire process, making this overhead negligible compared to each thread's processing time. Moreover, each thread now processed the entire <code>temp_data</code> belonging to its z slice, so memory access was more efficient, reducing the memory I/O wait time and improving the overall processing time. Additional benefits were due to the fact that some variables could be reused within each thread across loop iterations, minimizing memory allocations and deallocations. The overall effect was to reduce the total run-time down to ~0.16 secs, a 160x speedup compared to the original (25 secs). As my client said: "<i>You sped up [the application] from practically useless to clinically useful</i>."<br />
The lesson: try to minimize MEX invocation and thread creation/disposal overheads, and let the threads process as large adjacent memory blocks as possible.</p>
<h3 id="debugging">Debugging MEX files</h3>
<p>When debugging multi-threaded MEX functions, I find that it's often easier to run the function in single-threaded mode to debug the core logic, and once this is ready we can switch back multi-threading. This can easily be done by setting the number of threads outside the MEX function using Matlab's builtin <i><b><a href="https://www.mathworks.com/help/matlab/ref/maxnumcompthreads.html" rel="nofollow" target="_blank">maxNumCompThreads</a></b></i> function:</p>
<pre lang="matlab">
Nthreads = maxNumCompThreads(1);  % temporarily use only 1 thread for debugging
max_in_place(matrix1, matrix2);
maxNumCompThreads(Nthreads);      % restore previous value
%maxNumCompThreads('automatic');  % alternative
</pre>
<p>Once debugging is done and the MEX function works properly, we should remove the <i><b>maxNumCompThreads</b></i> calls, so that the MEX function will use the regular number of Matlab computational threads, which should be the same as the number of cores: <a href="/articles/undocumented-feature-function" target="_blank">feature('numCores')</a>.<br />
I typically like to use Eclipse as my IDE for non-Matlab code (Java, C/C++ etc.). Unfortunately, there's a problem attaching Eclipse to Matlab processes (which is necessary for interactive MEX debugging) if you're using any recent (post-2015) version of MinGW and Eclipse. This problem is due to a <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=474311" rel="nofollow" target="_blank">known Eclipse bug</a>, as user Lithe <a href="https://www.mathworks.com/matlabcentral/answers/241291-how-to-debug-mex-file-compiled-with-mingw64-and-g-flags#comment_461391" rel="nofollow" target="_blank">pointed out</a>. The workaround is to install an old version of MinGW, *in addition* to your existing MinGW version. <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=474311#c15" rel="nofollow" target="_blank">Reportedly</a>, only versions <a href="https://sourceforge.net/projects/tdm-gcc/files/TDM-GCC%20Installer/Previous/1.1309.0/" rel="nofollow" target="_blank">4.9.1 or older</a> of MinGW include gdb 7.8 (which is still supported by Eclipse), whereas newer versions of MinGW include a newer gdb that is not supported. Download and install such an old MinGW version in a separate folder from your more-modern compiler. Don't update your MEX to use the older MinGW - just tell Eclipse to use the version of gdb in the old MinGW bin/ folder when you set up a debug configuration for debugging your MEX files.<br />
Once you have a compatible gdb, and ask Eclipse to attach to a process, the processes list will finally appear (it won't with an incompatible gdb). Use <code><a href="/articles/undocumented-feature-function" target="_blank">feature('getPID')</a></code> to get your Matlab process ID, which can then used to attach to the relevant process in the Eclipse Attach-to-process window. For example, if your Matlab's PID is 4321, then the Matlab process will be called "Program - 4321" in Eclipse's processes list.<br />
I wish that MathWorks would update their <a href="https://www.mathworks.com/matlabcentral/answers/241291-how-to-debug-mex-file-compiled-with-mingw64-and-g-flags" rel="nofollow" target="_blank">official Answer</a> and their <a href="https://www.mathworks.com/matlabcentral/fileexchange/52848-matlab-support-for-mingw-w64-c-c-compiler" rel="nofollow" target="_blank">MinGW support package on File Exchange</a> to include this information, because without it debugging on Eclipse becomes impossible. Eclipse is so powerful, easy-to-use and ubiquitous that it's a shame for most users not to be able to work with it just because the workarounds above are not readily explained.<br />
N.B. If you don't like Eclipse, you can also use Visual Studio Code (VS Code), as Andy Campbell <a href="https://blogs.mathworks.com/developer/2018/06/19/mex-debugging-vscode" rel="nofollow" target="_blank">recently explained</a> in the MathWorks Developers' blog.</p>
<h3 id="consulting">Consulting</h3>
<p>Do you have any Matlab code that could use a bit (or a lot) of speeding-up? If so, please <a href="/consulting#request" target="_blank">contact me</a> for a private consulting offer. I can't promise to speed up your code by a similar factor of 160x, but you never know...</p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/multi-threaded-mex">Multi-threaded Mex</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/explicit-multi-threading-in-matlab-part4" rel="bookmark" title="Explicit multi-threading in Matlab part 4">Explicit multi-threading in Matlab part 4 </a> <small>Matlab performance can be improved by employing timer objects and spawning external processes. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/explicit-multi-threading-in-matlab-part3" rel="bookmark" title="Explicit multi-threading in Matlab part 3">Explicit multi-threading in Matlab part 3 </a> <small>Matlab performance can be improved by employing POSIX threads in C/C++ code. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/explicit-multi-threading-in-matlab-part2" rel="bookmark" title="Explicit multi-threading in Matlab part 2">Explicit multi-threading in Matlab part 2 </a> <small>Matlab performance can be improved by employing .Net (C#, VB, F# or C++) threads. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/multi-line-uitable-column-headers" rel="bookmark" title="Multi-line uitable column headers">Multi-line uitable column headers </a> <small>Matlab uitables can present long column headers in multiple lines, for improved readability. ...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://undocumentedmatlab.com/articles/multi-threaded-mex/feed</wfw:commentRss>
			<slash:comments>6</slash:comments>
		
		
			</item>
		<item>
		<title>String/char compatibility</title>
		<link>https://undocumentedmatlab.com/articles/string-char-compatibility?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=string-char-compatibility</link>
					<comments>https://undocumentedmatlab.com/articles/string-char-compatibility#comments</comments>
		
		<dc:creator><![CDATA[Yair Altman]]></dc:creator>
		<pubDate>Thu, 28 Jun 2018 12:57:59 +0000</pubDate>
				<category><![CDATA[Low risk of breaking in future versions]]></category>
		<category><![CDATA[Semi-documented function]]></category>
		<category><![CDATA[Pure Matlab]]></category>
		<guid isPermaLink="false">http://undocumentedmatlab.com/?p=7710</guid>

					<description><![CDATA[<p>Backward compatibility of strings in function inputs is a challenge, that can be assisted with an undocumented builtin  function. </p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/string-char-compatibility">String/char compatibility</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/sliders-in-matlab-gui-part-2" rel="bookmark" title="Sliders in Matlab GUI &#8211; part 2">Sliders in Matlab GUI &#8211; part 2 </a> <small>Matlab contains a variety of ways to define/display slider controls in GUI windows. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/converting-java-vectors-to-matlab-arrays" rel="bookmark" title="Converting Java vectors to Matlab arrays">Converting Java vectors to Matlab arrays </a> <small>Converting Java vectors to Matlab arrays is pretty simple - this article explains how....</small></li>
<li><a href="https://undocumentedmatlab.com/articles/types-of-undocumented-matlab-aspects" rel="bookmark" title="Types of undocumented Matlab aspects">Types of undocumented Matlab aspects </a> <small>This article lists the different types of undocumented/unsupported/hidden aspects in Matlab...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/ismembc-undocumented-helper-function" rel="bookmark" title="ismembc &#8211; undocumented helper function">ismembc &#8211; undocumented helper function </a> <small>Matlab has several undocumented internal helper functions that can be useful on their own in some cases. This post presents the ismembc function....</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<p>In numerous functions that I wrote over the years, some input arguments were expected to be strings in the old sense, i.e. char arrays for example, <code>'on'</code> or <code>'off'</code>. Matlab release R2016b introduced the concept of <a href="https://www.mathworks.com/help/matlab/characters-and-strings.html" rel="nofollow" target="_blank">string objects</a>, which can be created using the <i><b>string</b></i> function or [starting in R2017a] double quotes (<code>"on"</code>).<br />
The problem is that I have numerous functions that supported the old char-based strings but not the new string objects. If someone tries to enter a string object (<code>"on"</code>) as input to a function that expects a char-array (<code>'on'</code>), in many cases Matlab will error. This by itself is very unfortunate &#8211; I would have liked everything to be fully backward-compatible. But unfortunately this is not the case: MathWorks did invest effort in making the new strings backward-compatible to some degree (for example, graphic object property names/values and many internal functions that now accept either form as input). However, backward compatibility of strings is not 100% perfect.<br />
In such cases, the only solution is to make the function accept both forms (char-arrays and string objects), for example, by type-casting all such inputs as char-arrays using the builtin <i><b>char</b></i> function. If we do this at the top of our function, then the rest of the function can remain unchanged. For example:<br />
<span id="more-7710"></span></p>
<pre lang="matlab" highlight="2-4">
function test(stage)
   if isa(stage,'string')
      stage = char(stage);
   end
   % from this point onward, we don't need to worry about string inputs - any such strings will become plain-ol' char-arrays
   switch stage
      case 'stage 1', ...
      case 'stage 2', ...
      ...
   end
end
</pre>
<p>That was simple enough. But what if our function expects complex inputs (cell-arrays, structs etc.) that may contain strings in only some of their cells/fields?<br />
Luckily, Matlab contains an internal utility function that can help us: <i><b>controllib.internal.util.hString2Char</b></i>. This function, whose Matlab source-code is available (<i>%matlabroot%/toolbox/shared/controllib/general/+controllib/+internal/+util/hString2Char.m</i>) recursively scans the input value and converts any string object into the corresponding char-array, leaving all other data-types unchanged. For example:</p>
<pre lang="matlab">
>> controllib.internal.util.hString2Char({123, 'char-array', "a string"})
ans =
  1×3 cell array
    {[123]}    {'char-array'}    {'a string'}
>> controllib.internal.util.hString2Char(struct('a',"another string", 'b',pi))
ans =
  struct with fields:
    a: 'another string'
    b: 3.14159265358979
</pre>
<p>In order to keep our code working not just on recent releases (that support strings and <i><b>controllib.internal.util.hString2Char</b></i>) but also on older Matlab releases (where they did not exist), we simply wrap the call to <i><b>hString2Char</b></i> within a <i><b>try</b></i>&#8211;<i><b>catch</b></i> block. The adaptation of our function might then look as follows:</p>
<pre lang="matlab" highlight="2">
function test(varargin)
   try varargin = controllib.internal.util.hString2Char(varargin); catch, end
   % from this point onward, we don't need to worry about string inputs - any such strings will become plain-ol' char-arrays
   ...
end
</pre>
<p>Note that <i><b>controllib.internal.util.hString2Char</b></i> is a semi-documented function: it contains a readable internal help section (accessible via <code>help controllib.internal.util.hString2Char</code>), but not a doc-page. Nor is this function mentioned anywhere in Matlab&#8217;s official documentation. I think that this is a pity, because it&#8217;s such a useful little helper function.</p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/string-char-compatibility">String/char compatibility</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/sliders-in-matlab-gui-part-2" rel="bookmark" title="Sliders in Matlab GUI &#8211; part 2">Sliders in Matlab GUI &#8211; part 2 </a> <small>Matlab contains a variety of ways to define/display slider controls in GUI windows. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/converting-java-vectors-to-matlab-arrays" rel="bookmark" title="Converting Java vectors to Matlab arrays">Converting Java vectors to Matlab arrays </a> <small>Converting Java vectors to Matlab arrays is pretty simple - this article explains how....</small></li>
<li><a href="https://undocumentedmatlab.com/articles/types-of-undocumented-matlab-aspects" rel="bookmark" title="Types of undocumented Matlab aspects">Types of undocumented Matlab aspects </a> <small>This article lists the different types of undocumented/unsupported/hidden aspects in Matlab...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/ismembc-undocumented-helper-function" rel="bookmark" title="ismembc &#8211; undocumented helper function">ismembc &#8211; undocumented helper function </a> <small>Matlab has several undocumented internal helper functions that can be useful on their own in some cases. This post presents the ismembc function....</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://undocumentedmatlab.com/articles/string-char-compatibility/feed</wfw:commentRss>
			<slash:comments>18</slash:comments>
		
		
			</item>
		<item>
		<title>Blocked wait with timeout for asynchronous events</title>
		<link>https://undocumentedmatlab.com/articles/blocked-wait-with-timeout-for-asynchronous-events?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=blocked-wait-with-timeout-for-asynchronous-events</link>
					<comments>https://undocumentedmatlab.com/articles/blocked-wait-with-timeout-for-asynchronous-events#respond</comments>
		
		<dc:creator><![CDATA[Yair Altman]]></dc:creator>
		<pubDate>Sun, 13 May 2018 20:22:08 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Listeners]]></category>
		<category><![CDATA[Low risk of breaking in future versions]]></category>
		<category><![CDATA[Memory]]></category>
		<category><![CDATA[Performance]]></category>
		<guid isPermaLink="false">http://undocumentedmatlab.com/?p=7620</guid>

					<description><![CDATA[<p>It is easy to convert asynchronous (streaming) events into a blocked wait in Matlab. </p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/blocked-wait-with-timeout-for-asynchronous-events">Blocked wait with timeout for asynchronous events</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/waiting-for-asynchronous-events" rel="bookmark" title="Waiting for asynchronous events">Waiting for asynchronous events </a> <small>The Matlab waitfor function can be used to wait for asynchronous Java/ActiveX events, as well as with timeouts. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/udd-events-and-listeners" rel="bookmark" title="UDD Events and Listeners">UDD Events and Listeners </a> <small>UDD event listeners can be used to listen to property value changes and other important events of Matlab objects...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/matlab-callbacks-for-java-events" rel="bookmark" title="Matlab callbacks for Java events">Matlab callbacks for Java events </a> <small>Events raised in Java code can be caught and handled in Matlab callback functions - this article explains how...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/detecting-window-focus-events" rel="bookmark" title="Detecting window focus events">Detecting window focus events </a> <small>Matlab does not have any documented method to detect window focus events (gain/loss). This article describes an undocumented way to detect such events....</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<p>Readers of this website may have noticed that I have recently added an <a href="/iqml" rel="nofollow" target="_blank">IQML section</a> to the website&#8217;s top menu bar. IQML is a software connector that connects Matlab to DTN&#8217;s IQFeed, a financial data-feed of live and historic market data. IQFeed, like most other data-feed providers, sends its data in asynchronous messages, which need to be processed one at a time by the receiving client program (Matlab in this case). I wanted IQML to provide users with two complementary modes of operation:<br />
<span class="alignright"><a href="/iqml" rel="nofollow" target="_blank"><img loading="lazy" decoding="async" src="https://undocumentedmatlab.com/images/IQML.png" title="IQML's IQFeed-Matlab connectivity" alt="IQML's IQFeed-Matlab connectivity" width="426" height="213"/></a></span></p>
<ul>
<li><b>Streaming</b> (asynchronous, non-blocking) &#8211; incoming server data is processed by internal callback functions in the background, and is made available for the user to query at any later time.</li>
<li><b>Blocking</b> (synchronously waiting for data) &#8211; in this case, the main Matlab processing flows waits until the data arrives, or until the specified timeout period has passed &#8211; whichever comes first.</li>
</ul>
<p>Implementing streaming mode is relatively simple in general &#8211; all we need to do is ensure that the underlying connector object passes the incoming server messages to the relevant Matlab function for processing, and ensure that the user has some external way to access this processed data in Matlab memory (in practice making the connector object pass incoming data messages as Matlab callback events may be non-trivial, but that&#8217;s a separate matter &#8211; <a href="/articles/matlab-callbacks-for-java-events" target="_blank">read here</a> for details).<br />
In today&#8217;s article I&#8217;ll explain how we can implement a blocking mode in Matlab. It may sound difficult but it turns out to be relatively simple.<br />
I had several requirements/criteria for my blocked-wait implementation:</p>
<ol>
<li><b>Compatibility</b> &#8211; It had to work on all Matlab platforms, and all Matlab releases in the past decade (which rules out using Microsoft Dot-NET objects)</li>
<li><b>Ease-of-use</b> &#8211; It had to work out-of-the-box, with no additional installation/configuration (which ruled out using Perl/Python objects), and had to use a simple interface function</li>
<li><b>Timeout</b> &#8211; It had to implement a timed-wait, and had to be able to tell whether the program proceeded due to a timeout, or because the expected event has arrived</li>
<li><b>Performance</b> &#8211; It had to have minimal performance overhead</li>
</ol>
<p><span id="more-7620"></span></p>
<h3 id="basic">The basic idea</h3>
<p>The basic idea is to use Matlab&#8217;s builtin <i><b>waitfor</b></i>, as I explained in <a href="/articles/waiting-for-asynchronous-events" target="_blank">another post</a> back in 2012. If our underlying connector object has some settable boolean property (e.g., <code>Done</code>) then we can set this property in our event callback, and then <code>waitfor(object,'Done')</code>. The timeout mechanism is implemented using a dedicated timer object, as follows:</p>
<pre lang="matlab">
% Wait for data updates to complete (isDone = false if timeout, true if event has arrived)
function isDone = waitForDone(object, timeout)
    % Initialize: timeout flag = false
    object.setDone(false);
    % Create and start the separate timeout timer thread
    hTimer = timer('TimerFcn',@(h,e)object.setDone(true), 'StartDelay',timeout);
    start(hTimer);
    % Wait for the object property to change or for timeout, whichever comes first
    waitfor(object,'Done');
    % waitfor is over - either because of timeout or because the data changed
    % To determine which, check whether the timer callback was activated
    isDone = isvalid(hTimer) && hTimer.TasksExecuted == 0;
    % Delete the timer object
    try stop(hTimer);   catch, end
    try delete(hTimer); catch, end
    % Return the flag indicating whether or not timeout was reached
end  % waitForDone
</pre>
<p>where the event callback is responsible for invoking <code>object.setDone(true)</code> when the server data arrives. The usage would then be similar to this:</p>
<pre lang="matlab">
requestDataFromServer();
if isBlockingMode
   % Blocking mode - wait for data or timeout (whichever comes first)
   isDone = waitForDone(object, 10.0);  % wait up to 10 secs for data to arrive
   if ~isDone  % indicates a timeout
      fprintf(2, 'No server data has arrived within the specified timeout period!\n')
   end
else
   % Non-blocking (streaming) mode - continue with regular processing
end
</pre>
<h3 id="generic">Using a stand-alone generic signaling object</h3>
<p>But what can we do if we don&#8217;t have such a <code>Done</code> property in our underlying object, or if we do not have programmatic access to it?<br />
We could create a new non-visible figure and then <i><b>waitfor</b></i> one of its properties (e.g. <code>Resize</code>). The property would be initialized to <code>'off'</code>, and within both the event and timer callbacks we would set it to <code>'on'</code>, and then <code>waitfor(hFigure,'Resize','on')</code>. However, figures, even if non-visible, are quite heavy objects in terms of both memory, UI resources, and performance.<br />
It would be preferable to use a much lighter-weight object, as long as it abides by the other criteria above. Luckily, there are numerous such objects in Java, which is bundled in every Matlab since 2000, on every Matlab platform. As long as we choose a small Java object that has existed forever, we should be fine. For example, we could use a simple <code>javax.swing.JButton</code> and its boolean property <code>Enabled</code>:</p>
<pre lang="matlab">
hSemaphore = handle(javax.swing.JButton);  % waitfor() expects a handle() object, not a "naked" Java reference
% Wait for data updates to complete (isDone = false if timeout, true if event has arrived)
function isDone = waitForDone(hSemaphore, timeout)
    % Initialize: timeout flag = false
    hSemaphore.setEnabled(false);
    % Create and start the separate timeout timer thread
    hTimer = timer('TimerFcn',@(h,e)hSemaphore.setEnabled(true), 'StartDelay',timeout);
    start(hTimer);
    % Wait for the object property to change or for timeout, whichever comes first
    waitfor(hSemaphore,'Enabled');
    % waitfor is over - either because of timeout or because the data changed
    % To determine which, check whether the timer callback was activated
    isDone = isvalid(hTimer) && hTimer.TasksExecuted == 0;
    % Delete the timer object
    try stop(hTimer);   catch, end
    try delete(hTimer); catch, end
    % Return the flag indicating whether or not timeout was reached
end  % waitForDone
</pre>
<p>In this implementation, we would need to pass the <code>hSemaphore</code> object handle to the event callback, so that it would be able to invoke <code>hSemaphore.setEnabled(true)</code> when the server data has arrived.<br />
Under the hood, note that <code>Enabled</code> is not a true &#8220;property&#8221; of <code>javax.swing.JButton</code>, but rather exposes two simple public getter/setter methods (<i>setEnabled()</i> and <i>isEnabled()</i>), which Matlab interprets as a &#8220;property&#8221;. For all intents and purposes, in our Matlab code we can treat <code>Enabled</code> as a property of <code>javax.swing.JButton</code>, including its use by Matlab&#8217;s builtin <i><b>waitfor</b></i> function.<br />
There is a light overhead to this: on my laptop the <i><b>waitfor</b></i> function returns ~20 mSecs after the invocation of <code>hSemaphore.setEnabled(true)</code> in the timer or event callback &#8211; in many cases this overhead is negligible compared to the networking latencies for the blocked data request. When event reactivity is of utmost importance, users can always use streaming (non-blocking) mode, and process the incoming data events immediately in a callback.<br />
Of course, it would have been best if MathWorks would add a timeout option and return value to Matlab&#8217;s builtin <i><b>waitfor</b></i> function, similar to my <code>waitForDone</code> function &#8211; this would significantly simplify the code above. But until this happens, you can use <code>waitForDone</code> pretty-much as-is. I have used similar combinations of blocking and streaming modes with multiple other connectors that I implemented over the years (Interactive Brokers, CQG, Bloomberg and Reuters for example), and the bottom line is that it actually works well in practice.<br />
<a href="/consulting" target="_blank">Let me know</a> if you&#8217;d like me to assist with your own Matlab project or data connector, either developing it from scratch or improving your existing code. I will be visiting Boston and New York in early June and would be happy to meet you in person to discuss your specific needs.</p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/blocked-wait-with-timeout-for-asynchronous-events">Blocked wait with timeout for asynchronous events</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/waiting-for-asynchronous-events" rel="bookmark" title="Waiting for asynchronous events">Waiting for asynchronous events </a> <small>The Matlab waitfor function can be used to wait for asynchronous Java/ActiveX events, as well as with timeouts. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/udd-events-and-listeners" rel="bookmark" title="UDD Events and Listeners">UDD Events and Listeners </a> <small>UDD event listeners can be used to listen to property value changes and other important events of Matlab objects...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/matlab-callbacks-for-java-events" rel="bookmark" title="Matlab callbacks for Java events">Matlab callbacks for Java events </a> <small>Events raised in Java code can be caught and handled in Matlab callback functions - this article explains how...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/detecting-window-focus-events" rel="bookmark" title="Detecting window focus events">Detecting window focus events </a> <small>Matlab does not have any documented method to detect window focus events (gain/loss). This article describes an undocumented way to detect such events....</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://undocumentedmatlab.com/articles/blocked-wait-with-timeout-for-asynchronous-events/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Speeding-up builtin Matlab functions &#8211; part 2</title>
		<link>https://undocumentedmatlab.com/articles/speeding-up-builtin-matlab-functions-part-2?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=speeding-up-builtin-matlab-functions-part-2</link>
					<comments>https://undocumentedmatlab.com/articles/speeding-up-builtin-matlab-functions-part-2#comments</comments>
		
		<dc:creator><![CDATA[Yair Altman]]></dc:creator>
		<pubDate>Sun, 06 May 2018 16:26:19 +0000</pubDate>
				<category><![CDATA[Low risk of breaking in future versions]]></category>
		<category><![CDATA[Stock Matlab function]]></category>
		<category><![CDATA[Toolbox]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Pure Matlab]]></category>
		<guid isPermaLink="false">http://undocumentedmatlab.com/?p=7533</guid>

					<description><![CDATA[<p>Built-in Matlab functions can often be profiled and optimized for improved run-time performance. This article shows a typical example. </p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/speeding-up-builtin-matlab-functions-part-2">Speeding-up builtin Matlab functions &#8211; part 2</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/speeding-up-builtin-matlab-functions-part-1" rel="bookmark" title="Speeding-up builtin Matlab functions &#8211; part 1">Speeding-up builtin Matlab functions &#8211; part 1 </a> <small>Built-in Matlab functions can often be profiled and optimized for improved run-time performance. This article shows a typical example. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/speeding-up-matlab-jdbc-sql-queries" rel="bookmark" title="Speeding up Matlab-JDBC SQL queries">Speeding up Matlab-JDBC SQL queries </a> <small>Fetching SQL ResultSet data from JDBC into Matlab can be made significantly faster. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/callback-functions-performance" rel="bookmark" title="Callback functions performance">Callback functions performance </a> <small>Using anonymous functions in Matlab callbacks can be very painful for performance. Today's article explains how this can be avoided. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/undocumented-mouse-pointer-functions" rel="bookmark" title="Undocumented mouse pointer functions">Undocumented mouse pointer functions </a> <small>Matlab contains several well-documented functions and properties for the mouse pointer. However, some very-useful functions have remained undocumented and unsupported. This post details their usage....</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<p>Last week <a href="/articles/speeding-up-builtin-matlab-functions-part-1" target="_blank">I showed</a> how we can speed-up built-in Matlab functions, by creating local copies of the relevant m-files and then optimizing them for improved speed using a variety of techniques.<span class="alignright"><img loading="lazy" decoding="async" src="https://undocumentedmatlab.com/images/speedometer3b3_200x200.gif" alt="Accelerating MATLAB Performance" title="Accelerating MATLAB Performance" width="200" height="200" /></span> Today I will show another example of such speed-up, this time of the Financial Toolbox&#8217;s <i><b><a href="https://www.mathworks.com/help/finance/maxdrawdown.html" rel="nofollow" target="_blank">maxdrawdown</a></b></i> function, which is <a href="https://www.investopedia.com/terms/m/maximum-drawdown-mdd.asp" rel="nofollow" target="_blank">widely used</a> to estimate the relative risk of a trading strategy or asset. One might think that such a basic indicator would be optimized for speed, but experience shows otherwise. In fact, this function turned out to be the main run-time performance hotspot for one of my clients. The vast majority of his code was optimized for speed, and he naturally assumed that the built-in Matlab functions were optimized as well, but this was not the case. Fortunately, I was able to create an equivalent version that was 30-40 times faster (!), and my client remains a loyal Matlab fan.<br />
In today&#8217;s post I will show how I achieved this speed-up, using different methods than the ones I showed last week. A combination of these techniques can be used in a wide range of other Matlab functions. Additional speed-up techniques can be found in other <a href="/articles/tag/performance" target="_blank">performance-related posts</a> on this website, as well in my book <a href="/books/matlab-performance" target="_blank"><b>Accelerating MATLAB Performance</b></a>.<br />
<span id="more-7533"></span></p>
<h3 id="profiling">Profiling</h3>
<p>As I explained last week, the first step in speeding up any function is to profile its current run-time behavior using Matlab&#8217;s builtin <a href="https://www.mathworks.com/help/matlab/matlab_prog/profiling-for-improving-performance.html" rel="nofollow" target="_blank">Profiler tool</a>, which can either be started from the Matlab Editor toolstrip (&#8220;Run and Time&#8221;) or via the <a href="https://www.mathworks.com/help/matlab/ref/profile.html" rel="nofollow" target="_blank"><i><b>profile</b></i></a> function.<br />
The profile report for the client&#8217;s function showed that it had two separate performance hotspots:</p>
<ol>
<li>Code that checks the drawdown format (optional 2nd input argument) against a set of allowed formats</li>
<li>Main code section that iteratively loops over the data-series values to compute the maximal drawdown</li>
</ol>
<p>In order top optimize the code, I copied <i>%matlabroot%/toolbox/finance/finance/maxdrawdown.m</i> to a local folder on the Matlab path, renaming the file (and the function) <i>maxdrawdn</i>, in order to avoid conflict with the built-in version.</p>
<h3 id="strings">Optimizing input args pre-processing</h3>
<p>The main problem with the pre-processing of the optional format input argument is the string comparisons, which are being done even when the default format is used (which is by far the most common case). String comparison are often more expensive than numerical computations. Each comparison by itself is very short, but when <i><b>maxdrawdown</b></i> is run in a loop (as it often is), the run-time adds up.<br />
Here&#8217;s a snippet of the original code:</p>
<pre lang="matlab">
if nargin < 2 || isempty(Format)
    Format = 'return';
end
if ~ischar(Format) || size(Format,1) ~= 1
    error(message('finance:maxdrawdown:InvalidFormatType'));
end
choice = find(strncmpi(Format,{'return','arithmetic','geometric'},length(Format)));
if isempty(choice)
    error(message('finance:maxdrawdown:InvalidFormatValue'));
end
</pre>
<p>An equivalent code, which avoids any string processing in the common default case, is faster, simpler and more readable:</p>
<pre lang="matlab">
if nargin < 2 || isempty(Format)
    choice = 1;
elseif ~ischar(Format) || size(Format,1) ~= 1
    error(message('finance:maxdrawdown:InvalidFormatType'));
else
    choice = find(strncmpi(Format,{'return','arithmetic','geometric'},length(Format)));
    if isempty(choice)
        error(message('finance:maxdrawdown:InvalidFormatValue'));
    end
end
</pre>
<p>The general rule is that whenever you have a common case, you should check it first, avoiding unnecessary processing downstream. Moreover, for improved run-time performance (although not necessarily maintainability), it is generally preferable to work with numbers rather than strings (<code>choice</code> rather than <code>Format</code>, in our case).</p>
<h3 id="vectorizing">Vectorizing the main loop</h3>
<p>The main processing loop uses a very simple yet inefficient iterative loop. I assume that the code was originally developed this way in order to assist debugging and to ensure correctness, and that once it was ready nobody took the time to also optimize it for speed. It looks something like this:</p>
<pre lang="matlab">
MaxDD = zeros(1,N);
MaxDDIndex = ones(2,N);
...
if choice == 1   % 'return' format
    MaxData = Data(1,:);
    MaxIndex = ones(1,N);
    for i = 1:T
        MaxData = max(MaxData, Data(i,:));
        q = MaxData == Data(i,:);
        MaxIndex(1,q) = i;
        DD = (MaxData - Data(i,:)) ./ MaxData;
        if any(DD > MaxDD)
            p = DD > MaxDD;
            MaxDD(p) = DD(p);
            MaxDDIndex(1,p) = MaxIndex(p);
            MaxDDIndex(2,p) = i;
        end
    end
else             % 'arithmetic' or 'geometric' formats
    ...
</pre>
<p>This loop can relatively easily be vectorized, making the code much faster, and arguably also simpler, more readable, and more maintainable:</p>
<pre lang="matlab">
if choice == 3
    Data = log(Data);
end
MaxDDIndex = ones(2,N);
MaxData = cummax(Data);
MaxIndexes = find(MaxData==Data);
DD = MaxData - Data;
if choice == 1	% 'return' format
    DD = DD ./ MaxData;
end
MaxDD = cummax(DD);
MaxIndex2 = find(MaxDD==DD,1,'last');
MaxIndex1 = MaxIndexes(find(MaxIndexes<=MaxIndex2,1,'last'));
MaxDDIndex(1,:) = MaxIndex1;
MaxDDIndex(2,:) = MaxIndex2;
MaxDD = MaxDD(end,:);
</pre>
<p>Let's make a short run-time and accuracy check - we can see that we achieved a 31-fold speedup (YMMV), and received the exact same results:</p>
<pre lang="matlab">
>> data = rand(1,1e7);
>> tic, [MaxDD1, MaxDDIndex1] = maxdrawdown(data); toc  % builtin Matlab function
Elapsed time is 7.847140 seconds.
>> tic, [MaxDD2, MaxDDIndex2] = maxdrawdn(data); toc  % our optimized version
Elapsed time is 0.253130 seconds.
>> speedup = round(7.847140 / 0.253130)
speedup =
    31
>> isequal(MaxDD1,MaxDD2) && isequal(MaxDDIndex1,MaxDDIndex2)  % check accuracy
ans =
  logical
   1
</pre>
<p><b><u>Disclaimer</u></b>: The code above seems to work (quite well in fact) for a 1D data vector. You'd need to modify it a bit to handle 2D data - the returned maximal drawdown are still computed correctly but not the returned indices, due to their computation using the <i><b>find</b></i> function. This modification is left as an exercise for the reader...</p>
<h3 id="related">Related functions</h3>
<p>Very similar code could be used for the corresponding <i>maxdrawup</i> function. Although this function is used much less often than <i><b>maxdrawdown</b></i>, it is in fact widely used and very similar to <i><b>maxdrawdown</b></i>, so it is surprising that it is missing in the Financial Toolbox. Here is the corresponding code snippet:</p>
<pre lang="matlab">
% Code snippet for maxdrawup (similar to maxdrawdn)
MaxDUIndex = ones(2,N);
MinData = cummin(Data);
MinIndexes = find(MinData==Data);
DU = Data - MinData;
if choice == 1	% 'return' format
    DU = DU ./ MinData;
end
MaxDU = cummax(DU);
MaxIndex = find(MaxDD==DD,1,'last');
MinIndex = MinIndexes(find(MinIndexes<=MaxIndex,1,'last'));
MaxDUIndex(1,:) = MinIndex;
MaxDUIndex(2,:) = MaxIndex;
MaxDU = MaxDU(end,:);
</pre>
<p>Similar vectorization could be applied to the <i><b><a href="https://www.mathworks.com/help/finance/emaxdrawdown.html" rel="nofollow" target="_blank">emaxdrawdown</a></b></i> function. This too is left as an exercise for the reader...</p>
<h3 id="conclusions">Conclusions</h3>
<p>Matlab is composed of thousands of internal functions. Each and every one of these functions was meticulously developed and tested by engineers, who are after all only human. Whereas supreme emphasis is always placed with Matlab functions on their accuracy, run-time performance sometimes takes a back-seat. Make no mistake about this: code accuracy is almost always more important than speed (an exception are cases where some accuracy may be sacrificed for improved run-time performance). So I'm not complaining about the current state of affairs.<br />
But when we run into a specific run-time problem in our Matlab program, we should not despair if we see that built-in functions cause slowdown. We can try to avoid calling those functions (for example, by reducing the number of invocations, or limiting the target accuracy, etc.), or optimize these functions in our own local copy, as I've shown last week and today. There are multiple techniques that we could employ to improve the run time. Just use the profiler and keep an open mind about alternative speed-up mechanisms, and you'd be half-way there.<br />
<a href="/consulting" target="_blank">Let me know</a> if you'd like me to assist with your Matlab project, either developing it from scratch or improving your existing code, or just training you in how to improve your Matlab code's run-time/robustness/usability/appearance. I will be visiting Boston and New York in early June and would be happy to meet you in person to discuss your specific needs.</p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/speeding-up-builtin-matlab-functions-part-2">Speeding-up builtin Matlab functions &#8211; part 2</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/speeding-up-builtin-matlab-functions-part-1" rel="bookmark" title="Speeding-up builtin Matlab functions &#8211; part 1">Speeding-up builtin Matlab functions &#8211; part 1 </a> <small>Built-in Matlab functions can often be profiled and optimized for improved run-time performance. This article shows a typical example. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/speeding-up-matlab-jdbc-sql-queries" rel="bookmark" title="Speeding up Matlab-JDBC SQL queries">Speeding up Matlab-JDBC SQL queries </a> <small>Fetching SQL ResultSet data from JDBC into Matlab can be made significantly faster. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/callback-functions-performance" rel="bookmark" title="Callback functions performance">Callback functions performance </a> <small>Using anonymous functions in Matlab callbacks can be very painful for performance. Today's article explains how this can be avoided. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/undocumented-mouse-pointer-functions" rel="bookmark" title="Undocumented mouse pointer functions">Undocumented mouse pointer functions </a> <small>Matlab contains several well-documented functions and properties for the mouse pointer. However, some very-useful functions have remained undocumented and unsupported. This post details their usage....</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://undocumentedmatlab.com/articles/speeding-up-builtin-matlab-functions-part-2/feed</wfw:commentRss>
			<slash:comments>8</slash:comments>
		
		
			</item>
		<item>
		<title>Speeding-up builtin Matlab functions &#8211; part 1</title>
		<link>https://undocumentedmatlab.com/articles/speeding-up-builtin-matlab-functions-part-1?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=speeding-up-builtin-matlab-functions-part-1</link>
					<comments>https://undocumentedmatlab.com/articles/speeding-up-builtin-matlab-functions-part-1#comments</comments>
		
		<dc:creator><![CDATA[Yair Altman]]></dc:creator>
		<pubDate>Sun, 29 Apr 2018 09:46:29 +0000</pubDate>
				<category><![CDATA[Low risk of breaking in future versions]]></category>
		<category><![CDATA[Stock Matlab function]]></category>
		<category><![CDATA[Toolbox]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Pure Matlab]]></category>
		<guid isPermaLink="false">http://undocumentedmatlab.com/?p=7509</guid>

					<description><![CDATA[<p>Built-in Matlab functions can often be profiled and optimized for improved run-time performance. This article shows a typical example. </p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/speeding-up-builtin-matlab-functions-part-1">Speeding-up builtin Matlab functions &#8211; part 1</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/speeding-up-builtin-matlab-functions-part-2" rel="bookmark" title="Speeding-up builtin Matlab functions &#8211; part 2">Speeding-up builtin Matlab functions &#8211; part 2 </a> <small>Built-in Matlab functions can often be profiled and optimized for improved run-time performance. This article shows a typical example. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/speeding-up-matlab-jdbc-sql-queries" rel="bookmark" title="Speeding up Matlab-JDBC SQL queries">Speeding up Matlab-JDBC SQL queries </a> <small>Fetching SQL ResultSet data from JDBC into Matlab can be made significantly faster. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/callback-functions-performance" rel="bookmark" title="Callback functions performance">Callback functions performance </a> <small>Using anonymous functions in Matlab callbacks can be very painful for performance. Today's article explains how this can be avoided. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/undocumented-mouse-pointer-functions" rel="bookmark" title="Undocumented mouse pointer functions">Undocumented mouse pointer functions </a> <small>Matlab contains several well-documented functions and properties for the mouse pointer. However, some very-useful functions have remained undocumented and unsupported. This post details their usage....</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<p>A client recently asked me to assist with his numeric analysis function &#8211; it took 45 minutes to run, which was unacceptable (5000 runs of ~0.55 secs each).<span class="alignright"><img loading="lazy" decoding="async" src="https://undocumentedmatlab.com/images/speedometer4d_200x200.gif" alt="Accelerating MATLAB Performance" title="Accelerating MATLAB Performance" width="200" height="200" /></span> The code had to run in 10 minutes or less to be useful. It turns out that 99% of the run-time was taken up by Matlab&#8217;s built-in <a href="https://www.mathworks.com/help/stats/fitdist.html" rel="nofollow" target="_blank"><i><b>fitdist</b></i></a> function (part of the Statistics Toolbox), which my client was certain is already optimized for maximal performance. He therefore assumed that to get the necessary speedup he must either switch to another programming language (C/Java/Python), and/or upgrade his computer hardware at considerable expense, since parallelization was not feasible in his specific case.<br />
Luckily, I was there to assist and was able to quickly speed-up the code down to <b>7 minutes</b>, well below the required run-time. In today&#8217;s post I will show how I did this, which is relevant for a wide variety of other similar performance issues with Matlab. Many additional speed-up techniques can be found in other <a href="/articles/tag/performance" target="_blank">performance-related posts</a> on this website, as well in my book <a href="/books/matlab-performance" target="_blank"><b>Accelerating MATLAB Performance</b></a>.<br />
<span id="more-7509"></span></p>
<h3 id="profiling">Profiling</h3>
<p>The first step in speeding up any function is to profile its current run-time behavior using Matlab&#8217;s builtin <a href="https://www.mathworks.com/help/matlab/matlab_prog/profiling-for-improving-performance.html" rel="nofollow" target="_blank">Profiler tool</a>, which can either be started from the Matlab Editor toolstrip (&#8220;Run and Time&#8221;) or via the <a href="https://www.mathworks.com/help/matlab/ref/profile.html" rel="nofollow" target="_blank"><i><b>profile</b></i></a> function.<br />
The profile report for the client&#8217;s function showed that 99% of the time was spent in the Statistics Toolbox&#8217;s <i><b>fitdist</b></i> function. Drilling into this function in the profiling report, we see onion-like functions that processed input parameters, ensured data validation etc. The core processing is done inside a class that is unique to each required distribution (e.g., <code>prob.StableDistribution</code>, <code>prob.BetaDistribution</code> etc.) that is invoked within <i><b>fitdist</b></i> using an <i><b>feval</b></i> call, based on the distribution name that was specified by the user.<br />
In our specific case, the external onion layers of sanity checks were unnecessary and could be avoided. In general, I advise <i>not</i> to discard such checks, because you never know whether future uses might have a problem with outlier data or input parameters. Moreover, in the specific case of <i><b>fitdist</b></i> they take only a very minor portion of the run-time (this may be different in other cases, such as the <a href="/articles/ismembc-undocumented-helper-function" target="_blank"><i><b>ismember</b></i></a> function that I described years ago, where the sanity checks have a significant run-time impact compared to the core processing in the internal <i><b>ismembc</b></i> function).<br />
However, since we wanted to significantly improve the total run-time and this was spent within the distribution class (<code>prob.StableDistribution</code> in the case of my client), we continue to drill-down into this class to determine what can be done.<br />
It turns out that <code>prob.StableDistribution</code> basically does 3 things in its main <i>fit()</i> method:</p>
<ol>
<li>pre-process the input data (<i>prob.ToolboxFittableParametricDistribution.processFitArgs()</i> and <i>.removeCensoring()</i> methods) &#8211; this turned out to be unnecessary in my client&#8217;s data, but has little run-time impact.</li>
<li>call <i>stablefit()</i> in order to get fitting parameters &#8211; this took about half the run-time</li>
<li>call <i>stablelike()</i> in order to get likelihood data &#8211; this took about half the run-time as well</li>
<li>call <i>prob.StableDistribution.makeFitted()</i> to create a probability-distribution object returned to the caller &#8211; this also took little run-time that was not worth bothering about.</li>
</ol>
<h3 id="process">The speed-up improvement process</h3>
<p>With user-created code we could simply modify our code in-place. However, a more careful process is necessary when modifying built-in Matlab functions (either in the core Matlab distribution or in one of the toolboxes).<br />
The basic idea here is to create a side-function that would replicate the core processing of <i><b>fitdist</b></i>. This is preferable to modifying Matlab&#8217;s installation files because we could then reuse the new function in multiple computers, without having to mess around in the Matlab installation (which may not even be possible if we do not have admin privileges). Also, if we ever upgrade our Matlab we won&#8217;t need to remember to update the installed files (and obviously retest).<br />
I called the new function <i>fitdist2</i> and inside it I initially placed only the very core functionality of <i>prob.StableDistribution.fit()</i>:</p>
<pre lang="matlab">
% fitdist2 - fast replacement for fitdist(data,'stable')
% equivalent to pd = prob.StableDistribution.fit(data);
function pd = fitdist2(data)
    % Bypass pre-processing (not very important)
    [cens,freq,opt] = deal([]);
    %[data,cens,freq,opt] = prob.ToolboxFittableParametricDistribution.processFitArgs(data);
    %data = prob.ToolboxFittableParametricDistribution.removeCensoring(data,cens,freq,'stable');
    % Main processing in stablefit(), stablelike()
    params = stablefit(data,0.05,opt);
    [nll,cov] = stablelike(params,data);
    % Combine results into the returned probability distribution object
    pd = prob.StableDistribution.makeFitted(params,nll,cov,data,cens,freq);
end
</pre>
<p>If we try to run this as-is, we&#8217;d see errors because <i>stablefit()</i> and <i>stablelike()</i> are both sub-functions within <i>%matlabroot%/toolbox/stats/stats/+prob/StableDistribution.m</i>. So we copy these sub-functions (and their dependent subfunctions <i>infoMtxCal(), intMle(), tabpdf(), neglog_pdf(), stable_nloglf(), varTrans</i>) to the bottom of our <i>fitdist2.m</i> file, about 400 lines in total.<br />
We also remove places that call <i>checkargs(&#8230;)</i> since that seems to be unnecessary &#8211; if you want to keep it then add the <i>checkargs()</i> function as well.<br />
Now we re-run our code, after each speedup iteration verifying that the returned <code>pd</code> object returned by our <i>fitdist2</i> is equivalent to the original object returned by <i><b>fitdist</b></i>.</p>
<h3 id="stablefit">Speeding-up <i>stablefit()</i></h3>
<p>A new profiling run shows that the vast majority of the time in <i>stablefit()</i> is spent in two lines:</p>
<ol>
<li><code>s = load('private/StablePdfTable.mat');</code></li>
<li><code>[parmhat,~,err,output] = fminsearch(@(params)stable_nloglf(x,params),phi0,options);</code></li>
</ol>
<p>The first of these lines is reloading a static data file. The very same static data file is later reloaded in <i>stablelike()</i>. Both of these data-loads is done in every single invocation of <i><b>fitdist</b></i>, so if we have 5000 data fits, we load the same static data file 10,000 times! This is certainly not indicative of good programming practice. It would be much faster to reload the static data once into memory, and then use this cached data for the next 9,999 invocation. Since the original authors of <i>StableDistribution.m</i> seem to like single-character global variables (another bad programming practice, for multiple reasons), we&#8217;ll follow their example (added lines are highlighted):</p>
<pre lang="matlab" highlight="1-3,9">
persistent s  % this should have a more meaningful name (but at least is not global...)!
if isempty(s)
    fit_path = fileparts(which('fitdist'));
    s = load([fit_path '/private/StablePdfTable.mat']);
    a = s.a;
    b = s.b;
    xgd = s.xgd;
    p = s.p;
end
</pre>
<p>In order to speed-up the second line (that calls <b><i>fminsearch</i></b>), we can reduce the tolerances used by this function, by updating the <code>options</code> structure passed to it, so that we use tolerances of 1e-3 rather than the default 1e-6 (in our specific case this resulted in acceptable errors of ~0.1%). Specifically, we modify the code from this:</p>
<pre lang="matlab">
function [parmhat,parmci] = stablefit(x,alpha,options)
...
if nargin < 3 || isempty(options)
    options = statset('stablefit');
else
    options = statset(statset('stablefit'),options);
end
% Maximize the log-likelihood with respect to the transformed parameters
[parmhat,~,err,output] = fminsearch(@(params)stable_nloglf(x,params),phi0,options);
...
end
</pre>
<p>to this (note that the line that actually calls <b><i>fminsearch</i></b> remains unchanged):</p>
<pre lang="matlab" highlight="1,3-4,6-8">
function [parmhat,parmci] = stablefit(x,alpha,unused_options)
...
persistent options
if isempty(options)
    options = statset('stablefit');
    options.TolX   = 1e-3;
    options.TolFun = 1e-3;
    options.TolBnd = 1e-3;
end
% Maximize the log-likelihood with respect to the transformed parameters
[parmhat,~,err,output] = fminsearch(@(params)stable_nloglf(x,params),phi0,options);
...
end
</pre>
<p>The <i><b>fminsearch</b></i> internally calls <i>tabpdf()</i> repeatedly. Drilling down in the profiling report we see that it recomputes a <code>griddedInterpolant</code> object that is essentially the same for all iterations (and therefore a prime candidate for caching), and also that it uses the costly cubic interpolation rather than a more straight-forward linear interpolation:</p>
<pre lang="matlab" highlight="3-6">
function y = tabpdf(x,alpha,beta)
...
persistent G  % this should have a more meaningful name (but at least is not global...)!
if isempty(G)
    G = griddedInterpolant({b, a, xgd}, p, 'linear','none');  % 'linear' instead of 'cubic'
end
%G = griddedInterpolant({b, a, xgd}, p, 'cubic','none');  % original
y = G({beta,alpha,x});
...
</pre>
<p>These cases illustrate two important speedup technique categories: caching data in order to reduce the <i>number of times</i> that a certain code hotspot is being run, and modifying the parameters/inputs in order to reduce the <i>individual run-time</i> of the hotspot code. Variations of these techniques form the essence of effective speedup and can often be achieved by just reflecting on the problem and asking yourself two questions:</p>
<ol>
<li><i>can I reduce the number of times that this code is being run?</i> and</li>
<li><i>can I reduce the run-time of this specific code section?</i></li>
</ol>
<p>Additional important speed-up categories include parallelization, vectorization and algorithmic modification. These are sometimes more difficult programmatically and riskier in terms of functional equivalence, but may be required in case the two main techniques above are not feasible. Of course, we can always combine these techniques, we don't need to choose just one or the other.</p>
<h3 id="stablelike">Speeding-up <i>stablelike()</i></h3>
<p>We now turn our attentions to <i>stablelike()</i>. As for the loaded static file, we could simply use the cached <code>s</code> to load the data in order to avoid repeated reloading of the data from disk. But it turns out that this data is actually not used at all inside the function (!) so we just comment-out the old code:</p>
<pre lang="matlab">
%s = load('private/StablePdfTable.mat');
%a = s.a;
%b = s.b;
%xgd = s.xgd;
%p = s.p;
</pre>
<p>Think about this - the builtin Matlab code loads a data file from disk and then does <i>absolutely nothing</i> with it - what a waste!<br />
Another important change is to reduce the run-time of the <b><i>integral</i></b> function, which is called thousands of times within a double loop. We do this by reducing the tolerances specified in the <b><i>integral</i></b> call from 1e-6:</p>
<pre lang="matlab">
F(i,j) = integral(@(x)infoMtxCal(x,params,step,i,j),-Inf,Inf,'AbsTol',1e-6,'RelTol',1e-4); % original
F(i,j) = integral(@(x)infoMtxCal(x,params,step,i,j),-Inf,Inf,'AbsTol',1e-3,'RelTol',1e-3); % new
</pre>
<p>You can see that once again these two cases follow the two techniques that I mentioned above: we reduced the number of times that we load the data file (to 0 in our case), and we improved the run-time of the individual integral calculation by reducing its tolerances.</p>
<h3 id="conclusions">Conclusions</h3>
<p>The final result of applying the techniques above was a 6-fold speedup, reducing the total run-time from 45 minutes down to 7 minutes. I could probably have improved the run-time even further, but since we reached our target run-time I stopped there. The point after all was to make the code usable, not to reach a world speed record.<br />
In my next article I will present another example of dramatically improving the run-time speed of a built-in Matlab function, this time a very commonly-used function in the Financial Toolbox that I was able to speed-up by a factor of 40.<br />
Matlab releases improve continuously, so hopefully my techniques above (or alternatives) would find their way into the builtin Matlab functions, making them faster than today, out-of-the-box.<br />
Until this happens, we should not lose hope when faced with a slow Matlab function, even if it is a built-in/internal one, as I hope to have clearly illustrated today, and will also show in my next article. Improving the performance is often easy. In fact, it took me much longer to write this article than it was to improve my client's code...<br />
<a href="/consulting" target="_blank">Let me know</a> if you'd like me to assist with your Matlab project, either developing it from scratch or improving your existing code, or just training you in how to improve your Matlab code's run-time/robustness/usability/appearance. I will be visiting Boston and New York in early June and would be happy to meet you in person to discuss your specific needs.</p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/speeding-up-builtin-matlab-functions-part-1">Speeding-up builtin Matlab functions &#8211; part 1</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/speeding-up-builtin-matlab-functions-part-2" rel="bookmark" title="Speeding-up builtin Matlab functions &#8211; part 2">Speeding-up builtin Matlab functions &#8211; part 2 </a> <small>Built-in Matlab functions can often be profiled and optimized for improved run-time performance. This article shows a typical example. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/speeding-up-matlab-jdbc-sql-queries" rel="bookmark" title="Speeding up Matlab-JDBC SQL queries">Speeding up Matlab-JDBC SQL queries </a> <small>Fetching SQL ResultSet data from JDBC into Matlab can be made significantly faster. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/callback-functions-performance" rel="bookmark" title="Callback functions performance">Callback functions performance </a> <small>Using anonymous functions in Matlab callbacks can be very painful for performance. Today's article explains how this can be avoided. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/undocumented-mouse-pointer-functions" rel="bookmark" title="Undocumented mouse pointer functions">Undocumented mouse pointer functions </a> <small>Matlab contains several well-documented functions and properties for the mouse pointer. However, some very-useful functions have remained undocumented and unsupported. This post details their usage....</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://undocumentedmatlab.com/articles/speeding-up-builtin-matlab-functions-part-1/feed</wfw:commentRss>
			<slash:comments>7</slash:comments>
		
		
			</item>
		<item>
		<title>Adding custom properties to GUI objects</title>
		<link>https://undocumentedmatlab.com/articles/adding-custom-properties-to-gui-objects?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=adding-custom-properties-to-gui-objects</link>
					<comments>https://undocumentedmatlab.com/articles/adding-custom-properties-to-gui-objects#comments</comments>
		
		<dc:creator><![CDATA[Yair Altman]]></dc:creator>
		<pubDate>Thu, 15 Feb 2018 12:39:35 +0000</pubDate>
				<category><![CDATA[GUI]]></category>
		<category><![CDATA[Handle graphics]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Low risk of breaking in future versions]]></category>
		<category><![CDATA[Undocumented feature]]></category>
		<category><![CDATA[Pure Matlab]]></category>
		<category><![CDATA[schema.prop]]></category>
		<guid isPermaLink="false">http://undocumentedmatlab.com/?p=7324</guid>

					<description><![CDATA[<p>It is very easy to add custom user-defined properties and methods to GUI handles and Java references in Matlab. </p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/adding-custom-properties-to-gui-objects">Adding custom properties to GUI objects</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/adding-dynamic-properties-to-graphic-handles" rel="bookmark" title="Adding dynamic properties to graphic handles">Adding dynamic properties to graphic handles </a> <small>It is easy and very useful to attach dynamic properties to Matlab graphics objects in run-time. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/performance-accessing-handle-properties" rel="bookmark" title="Performance: accessing handle properties">Performance: accessing handle properties </a> <small>Handle object property access (get/set) performance can be significantly improved using dot-notation. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/borderless-button-used-for-plot-properties" rel="bookmark" title="Borderless button used for plot properties">Borderless button used for plot properties </a> <small>A borderless button can be used to add unobtrusive functionality to plot axes...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/udd-properties" rel="bookmark" title="UDD Properties">UDD Properties </a> <small>UDD provides a very convenient way to add customizable properties to existing Matlab object handles...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<p>Matlab objects have numerous built-in properties (some of them publicly-accessible/documented and others not, but that&#8217;s a different story). For various purposes, it is sometimes useful to attach custom user-defined properties to such objects. While there was never a fully-documented way to do this, most users simply attached such properties as fields in the <b>UserData</b> property or the object&#8217;s [hidden] <b>ApplicationData</b> property (accessible via the documented <i><b>setappdata</b></i>/<i><b>getappdata</b></i> functions).<br />
An undocumented way to attach actual new user-defined properties to objects such as GUI handles or Java references has historically (in HG1, up to R2014a) been to use the undocumented <i><b>schema.prop</b></i> function, as I <a href="/articles/adding-dynamic-properties-to-graphic-handles" target="_blank">explained here</a>. As I wrote in that post, in HG2 (R2014b onward), we can use the fully-documented <a href="https://www.mathworks.com/help/matlab/ref/dynamicprops.addprop.html" rel="nofollow" target="_blank"><i><b>addprop</b></i> function</a> to add new custom properties (and methods) to such objects. What is still NOT documented, as far as I could tell, is that all of Matlab&#8217;s builtin handle graphics objects indirectly inherit the <code>dynamicprops</code> class, which allows this. The bottom line is that we can dynamically add custom properties in run-time to any HG object, without affecting any other object. In other words, the new properties will only be added to the handles that we specifically request, and not to any others.<br />
All this is important, because for some unexplained reason that escapes my understanding, MathWorks chose to seal its classes, thus preventing users to extend them with sub-classes that contain the new properties. So much frustration could have been solved if MathWorks would simply remove the <b>Sealed</b> class meta-property from its classes. Then again, I&#8217;d have less to blog about in that case&#8230;<br />
Anyway, why am I rehashing old news that I have already reported a few years ago?<br />
Well, first, because my experience has been that this little tidbit is [still] fairly unknown by Matlab developers. Secondly, I happened to run into a perfect usage example a short while ago that called for this solution: a <a href="https://stackoverflow.com/questions/48597836/matlab-figure-age" rel="nofollow" target="_blank">StackExchange user asked</a> whether it is possible to tell a GUI figure&#8217;s age, in other words the elapsed time since the figure was created. The simple answer would be to use <i><b>setappdata</b></i> with the creation date whenever we create a figure. However, a &#8220;cleaner&#8221; approach seems to be to create new read-only properties for the figure&#8217;s <b>CreationTime</b> and <b>Age</b>:<br />
<span id="more-7324"></span><br />
First, create a small Matlab function as follows, that attaches the CreationTime property to a figure:</p>
<pre lang="matlab">
function setCreationTime(hFig,varargin)
   hProp = addprop(hFig,'CreationTime');
   hFig.CreationTime = now;
   hProp.SetAccess = 'private';  % make property read-only after setting its initial value
   hProp = addprop(hFig,'Age');
   hProp.GetMethod = @(h,e) etime(datevec(hFig.CreationTime), clock);  % compute on-the-fly
   hProp.SetAccess = 'private';  % make property read-only
end
</pre>
<p>Now assign this function as the default CreateFcn callback function for all new figures from now on:</p>
<pre lang="matlab">
set(0,'DefaultFigureCreateFcn',@setCreationTime)
</pre>
<p>That&#8217;s it &#8211; you&#8217;re done! Whenever a new figure will be created from now on, it will have two custom read-only properties: <b>CreationTime</b> and <b>Age</b>.<br />
For example:</p>
<pre lang="matlab">
>> newFig = figure;
>> newFig.CreationTime
ans =
      737096.613706748
>> ageInDays = now - newFig.CreationTime
ageInDays =
       0.0162507836846635
>> ageDuration = duration(ageInDays*24,0,0)
ageDuration =
  duration
   00:23:24
>> ageString = datestr(ageInDays, 'HH:MM:SS.FFF')
ageString =
    '00:23:24.068'
>> ageInSecs = newFig.Age
ageInSecs =
       1404.06771035492
</pre>
<p>Note that an alternative way to set the computed property <b>Age</b> would have been to set its value to be an anonymous function, but this would have necessitated invoking it with parenthesis (as in: <code>ageInSecs = newFig.Age()</code>). By setting the property&#8217;s <b>GetMethod</b> meta-property we avoid this need.<br />
Keen readers will have noticed that the mechanism that I outlined above for the <b>Age</b> property/method can also be used to add custom user methods. For example, we can create a new custom property named <b>refresh</b> that would be read-only and have a <b>GetMethod</b> which is the function handle of the function that refreshes the object in some way.<br />
Do you have any special uses for custom user-defined properties/methods in your program? or perhaps you have a use-case that might show MathWorks why sub-classing the built-in classes might improve your work? if so, then please place a comment about it below. If enough users show MathWorks why this is important, then maybe it will be fixed in some future release.</p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/adding-custom-properties-to-gui-objects">Adding custom properties to GUI objects</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/adding-dynamic-properties-to-graphic-handles" rel="bookmark" title="Adding dynamic properties to graphic handles">Adding dynamic properties to graphic handles </a> <small>It is easy and very useful to attach dynamic properties to Matlab graphics objects in run-time. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/performance-accessing-handle-properties" rel="bookmark" title="Performance: accessing handle properties">Performance: accessing handle properties </a> <small>Handle object property access (get/set) performance can be significantly improved using dot-notation. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/borderless-button-used-for-plot-properties" rel="bookmark" title="Borderless button used for plot properties">Borderless button used for plot properties </a> <small>A borderless button can be used to add unobtrusive functionality to plot axes...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/udd-properties" rel="bookmark" title="UDD Properties">UDD Properties </a> <small>UDD provides a very convenient way to add customizable properties to existing Matlab object handles...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://undocumentedmatlab.com/articles/adding-custom-properties-to-gui-objects/feed</wfw:commentRss>
			<slash:comments>6</slash:comments>
		
		
			</item>
		<item>
		<title>Customizing axes tick labels</title>
		<link>https://undocumentedmatlab.com/articles/customizing-axes-tick-labels?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=customizing-axes-tick-labels</link>
					<comments>https://undocumentedmatlab.com/articles/customizing-axes-tick-labels#comments</comments>
		
		<dc:creator><![CDATA[Yair Altman]]></dc:creator>
		<pubDate>Wed, 24 Jan 2018 13:38:26 +0000</pubDate>
				<category><![CDATA[Handle graphics]]></category>
		<category><![CDATA[Low risk of breaking in future versions]]></category>
		<category><![CDATA[Stock Matlab function]]></category>
		<category><![CDATA[HG2]]></category>
		<category><![CDATA[Pure Matlab]]></category>
		<guid isPermaLink="false">http://undocumentedmatlab.com/?p=7304</guid>

					<description><![CDATA[<p>Multiple customizations can be applied to tick labels. </p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/customizing-axes-tick-labels">Customizing axes tick labels</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/setting-axes-tick-labels-format" rel="bookmark" title="Setting axes tick labels format">Setting axes tick labels format </a> <small>Matlab plot axes ticks can be customized in a way that will automatically update whenever the tick values change. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-axes-part-5-origin-crossover-and-labels" rel="bookmark" title="Customizing axes part 5 &#8211; origin crossover and labels">Customizing axes part 5 &#8211; origin crossover and labels </a> <small>The axes rulers (axles) can be made to cross-over at any x,y location within the chart. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-axes-rulers" rel="bookmark" title="Customizing axes rulers">Customizing axes rulers </a> <small>HG2 axes can be customized in numerous useful ways. This article explains how to customize the rulers. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-axes-part-2" rel="bookmark" title="Customizing axes part 2">Customizing axes part 2 </a> <small>Matlab HG2 axes can be customized in many different ways. This article explains some of the undocumented aspects. ...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<p>In <a href="/articles/customizing-histogram-plots" target="_blank">last week&#8217;s post</a>, I discussed various ways to customize bar/histogram plots, including customization of the tick labels. While some of the customizations that I discussed indeed rely on undocumented properties/features, many Matlab users are not aware that tick labels can be individually customized, and that this is a <a href="https://www.mathworks.com/help/matlab/ref/matlab.graphics.axis.axes-properties.html#property_d119e51283" rel="nofollow" target="_blank">fully documented/supported functionality</a>. This relies on the fact that the default axes <b>TickLabelInterpreter</b> property value is <code>'tex'</code>, which supports a wide range of font customizations, individually for each label. This includes any combination of symbols, superscript, subscript, bold, italic, slanted, face-name, font-size and color &#8211; even intermixed within a single label. Since tex is the default interpreter, we don&#8217;t need any special preparation &#8211; simply set the relevant <b>X/Y/ZTickLabel</b> string to include the relevant tex markup.<br />
To illustrate this, have a look at the following <a href="https://stackoverflow.com/a/46181211/233829" rel="nofollow" target="_blank">excellent answer</a> by user Ubi on Stack Overflow:<br />
<figure style="width: 450px" class="wp-caption alignright"><img loading="lazy" decoding="async" src="https://i.stack.imgur.com/3vjhD.png" alt="Axes with Tex-customized tick labels" title="Axes with Tex-customized tick labels" width="450" height="300" /><figcaption class="wp-caption-text">Axes with Tex-customized tick labels</figcaption></figure></p>
<pre lang="matlab">
plot(1:10, rand(1,10))
ax = gca;
% Simply color an XTickLabel
ax.XTickLabel{3} = ['\color{red}' ax.XTickLabel{3}];
% Use TeX symbols
ax.XTickLabel{4} = '\color{blue} \uparrow';
% Use multiple colors in one XTickLabel
ax.XTickLabel{5} = '\color[rgb]{0,1,0}green\color{orange}?';
% Color YTickLabels with colormap
nColors = numel(ax.YTickLabel);
cm = jet(nColors);
for i = 1:nColors
    ax.YTickLabel{i} = sprintf('\\color[rgb]{%f,%f,%f}%s', cm(i,:), ax.YTickLabel{i});
end
</pre>
<p>In addition to <code>'tex'</code>, we can also set the axes object&#8217;s <b>TickLabelInterpreter</b> to <code>'latex'</code> for a Latex interpreter, or <code>'none'</code> if we want to use no string interpretation at all.<br />
As I showed in <a href="/articles/customizing-histogram-plots" target="_blank">last week&#8217;s post</a>, we can control the gap between the tick labels and the axle line, using the Ruler object&#8217;s undocumented <b>TickLabelGapOffset, TickLabelGapMultiplier</b> properties.<br />
Also, as I explained in other posts (<a href="/articles/customizing-axes-part-5-origin-crossover-and-labels" target="_blank">here</a> and <a href="/articles/customizing-axes-rulers#Exponent" target="_blank">here</a>), we can also control the display of the secondary axle label (typically exponent or units) using the Ruler&#8217;s similarly-undocumented <b>SecondaryLabel</b> property. Note that the related Ruler&#8217;s <b>Exponent</b> property is <a href="https://www.mathworks.com/help/matlab/ref/matlab.graphics.axis.decorator.numericruler-properties.html" rel="nofollow" target="_blank">documented/supported</a>, but simply sets a basic exponent label (e.g., <code>'\times10^{6}'</code> when <b>Exponent</b>==6) &#8211; to set a custom label string (e.g., <code>'\it\color{gray}Millions'</code>), or to modify its other properties (position, alignment etc.), we should use <b>SecondaryLabel</b>.</p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/customizing-axes-tick-labels">Customizing axes tick labels</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/setting-axes-tick-labels-format" rel="bookmark" title="Setting axes tick labels format">Setting axes tick labels format </a> <small>Matlab plot axes ticks can be customized in a way that will automatically update whenever the tick values change. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-axes-part-5-origin-crossover-and-labels" rel="bookmark" title="Customizing axes part 5 &#8211; origin crossover and labels">Customizing axes part 5 &#8211; origin crossover and labels </a> <small>The axes rulers (axles) can be made to cross-over at any x,y location within the chart. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-axes-rulers" rel="bookmark" title="Customizing axes rulers">Customizing axes rulers </a> <small>HG2 axes can be customized in numerous useful ways. This article explains how to customize the rulers. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-axes-part-2" rel="bookmark" title="Customizing axes part 2">Customizing axes part 2 </a> <small>Matlab HG2 axes can be customized in many different ways. This article explains some of the undocumented aspects. ...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://undocumentedmatlab.com/articles/customizing-axes-tick-labels/feed</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>Using SQLite in Matlab</title>
		<link>https://undocumentedmatlab.com/articles/using-sqlite-in-matlab?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=using-sqlite-in-matlab</link>
					<comments>https://undocumentedmatlab.com/articles/using-sqlite-in-matlab#comments</comments>
		
		<dc:creator><![CDATA[Yair Altman]]></dc:creator>
		<pubDate>Wed, 27 Dec 2017 21:53:54 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Low risk of breaking in future versions]]></category>
		<category><![CDATA[Undocumented feature]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[JDBC]]></category>
		<category><![CDATA[Performance]]></category>
		<guid isPermaLink="false">http://undocumentedmatlab.com/?p=7255</guid>

					<description><![CDATA[<p>SQLite databases can be accessed in a variety of different ways in Matlab. </p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/using-sqlite-in-matlab">Using SQLite in Matlab</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/secure-ssl-connection-between-matlab-and-postgresql" rel="bookmark" title="Secure SSL connection between Matlab and PostgreSQL">Secure SSL connection between Matlab and PostgreSQL </a> <small>It is tricky, but quite possible, to use SSL to connect Matlab to a PostgreSQL database. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/speeding-up-matlab-jdbc-sql-queries" rel="bookmark" title="Speeding up Matlab-JDBC SQL queries">Speeding up Matlab-JDBC SQL queries </a> <small>Fetching SQL ResultSet data from JDBC into Matlab can be made significantly faster. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/matlab-toolstrip-part-5-icons" rel="bookmark" title="Matlab toolstrip – part 5 (icons)">Matlab toolstrip – part 5 (icons) </a> <small>Icons can be specified in various ways for toolstrip controls and the app window itself. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/sending-html-emails-from-matlab" rel="bookmark" title="Sending HTML emails from Matlab">Sending HTML emails from Matlab </a> <small>Matlab's sendmail only sends simple text messages by default; a simple hack can cause it to send HTML-formatted messages. ...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<p>MathWorks invests a huge amount of effort in recent years on supporting large distributed databases. The business case for this focus is entirely understandable, but many Matlab users have much simpler needs, which are often served by the light-weight open-source <a href="http://sqlite.org" rel="nofollow" target="_blank">SQLite database</a> (which claims to be the most widely-used database worldwide). Although SQLite is very widely used, and despite the fact that built-in support for SQLite is included in Matlab (for its internal use), MathWorks has chosen not to expose any functionality or wrapper function that would enable end-users to access it. In any case, I recently came across a need to do just that, when a consulting client asked me to create an interactive data-browser for their SQLite database that would integrate with their Matlab program:<br />
<center><img decoding="async" src="https://undocumentedmatlab.com/images/DataBrowser_2.png" alt="SQLite data browser" title="SQLite data browser" width="80%" style="max-width:716px;" /></center><br />
In today&#8217;s post I will discuss several possible mechanisms to integrate SQLite in Matlab code, and you can take your pick among them. Except for the Database Toolbox, all the alternatives are free (open-source) libraries (even the commercial Database Toolbox relies on one of the open-source libraries, by the way).<br />
<span id="more-7255"></span></p>
<h3 id="sqlite4java">sqlite4java</h3>
<p><code>sqlite4java</code> is a Java package by <a href="http://almworks.com" rel="nofollow" target="_blank">ALM Works</a> that is bundled with Matlab for the past several years (in the <i>%matlabroot%/java/jarext/sqlite4java/</i> folder). This is a lightweight open-source package that provides a minimalist and fast (although not very convenient) interface to SQLite. You can either use the package that comes with your Matlab installation, or download and use the latest version from <a href="https://bitbucket.org/almworks/sqlite4java" rel="nofollow" target="_blank">the project repository</a>, where you can also find documentation.<br />
Mark Mikofski <a href="http://poquitopicante.blogspot.co.il/2015/03/sqlite-in-matlab.html" rel="nofollow" target="_blank">exposed</a> this hidden nugget back in 2015, and you are welcome to view his post for additional details. Here&#8217;s a sample usage:</p>
<pre lang="matlab">
% Open the DB data file
db = com.almworks.sqlite4java.SQLiteConnection(java.io.File('C:\Yair\Data\IGdb 2017-11-13.sqlite'));
db.open;
% Prepare an SQL query statement
stmt = db.prepare(['select * from data_table where ' conditionStr]);
% Step through the result set rows
row = 1;
while stmt.step
   numericValues(row) = stmt.columnInt(0);    % column #0
   stringValues{row}  = stmt.columnString(1); % column #1
end
% Cleanup
stmt.dispose
db.dispose
</pre>
<p>Note that since <code>sqlite4java</code> uses a proprietary interface (similar, but not identical, to JDBC), it can take a bit of time to get used to it. I am generally a big fan of preferring built-in components over externally-installed ones, but in this particular case I prefer other alternatives.</p>
<h3 id="JDBC">JDBC</h3>
<p><a href="http://www.oracle.com/technetwork/java/javase/jdbc/index.html" rel="nofollow" target="_blank">JDBC</a> (Java Database Connectivity) is the industry standard for connectivity to databases. Practically all databases nowadays have at least one JDBC connector, and many DBs have multiple JDBC drivers created by different groups. As long as they all adhere to the JDBC interface standard, these drivers are all equivalent and you can choose between them based on availability, cost, support, license, performance and other similar factors. SQLite is no exception to this rule, and has several JDBC driver implementations, including xerial&#8217;s <a href="https://bitbucket.org/xerial/sqlite-jdbc" rel="nofollow" target="_blank"><code>sqlite-jdbc</code></a> (also <a href="http://poquitopicante.blogspot.co.il/2015/03/sqlite-in-matlab.html" rel="nofollow" target="_blank">discussed by Mark Mikofski</a>) and <a href="https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/sqlitebot/sqlitejdbc-v056.jar" rel="nofollow" target="_blank"><code>sqlitejdbc</code></a>. If you ask me,<br />
 <code>sqlite-jdbc</code> is better as it is being maintained with new versions released periodically.<br />
The example above would look something like this with <code>sqlite-jdbc</code>:</p>
<pre lang="matlab">
% Add the downloaded JAR library file to the dynamic Java classpath
javaaddpath('C:\path\to\sqlite\sqlite-jdbc-3.21.0.jar')
% Open the DB file
jdbc = org.sqlite.JDBC;
props = java.util.Properties;
conn = jdbc.createConnection('jdbc:sqlite:C:\Yair\Data\IGdb 2017-11-13.sqlite',props);  % org.sqlite.SQLiteConnection object
% Prepare and run an SQL query statement
sqlStr = ['select * from data_table where ' conditionStr];
stmt = conn.createStatement;     % org.sqlite.jdbc4.JDBC4Statement object
rs = stmt.executeQuery(sqlStr);  % org.sqlite.jdbc4.JDBC4ResultSet object
% Step through the result set rows
rows = 1;
while rs.next
   numericValues(row) = rs.getLong('ID');
   stringValues{row}  = rs.getString('Name');
end
% Cleanup
rs.close
stmt.close
conn.close
</pre>
<h3 id="toolbox">Database toolbox</h3>
<p>In addition to all the above, MathWorks sells the Database Toolbox which has an <a href="https://www.mathworks.com/help/database/ug/working-with-the-matlab-interface-to-sqlite.html" rel="nofollow" target="_blank">integral SQLite connector</a>, in two flavors &#8211; native and JDBC (the JDBC connector is simply <code>sqlite-jdbc</code> that I mentioned above, see a <a href="https://gist.github.com/cbcunc/e2bc3ef170544e4bf0f0" rel="nofollow" target="_blank">short discussion here</a>).<br />
I assume that the availability of this feature in the DB toolbox is the reason why MathWorks has never created a documented wrapper function for the bundled <code>sqlite4java</code>. I could certainly understand this from a business perspective. Still, with so many free alternatives available as discussed in this post, I see not reason to purchase the toolbox merely for its SQLite connector. Then again, if you need to connect to several different database types, not just SQLite, then getting the toolbox might make sense.</p>
<h3 id="mksqlite">mksqlite</h3>
<p>My personal favorite is actually none of these Java-based connectors (surprise, surprise), but rather the open-source <a href="http://mksqlite.sourceforge.net" rel="nofollow" target="_blank"><code>mksqlite</code> connector</a> by <a href="http://www.kortmann.de" rel="nofollow" target="_blank">Martin Kortmann</a> and <a href="https://github.com/AndreasMartin72" rel="nofollow" target="_blank">Andreas Martin</a>. This is a native (Mex-file) connector that acts as a direct Matlab function. The syntax is pretty straight-forward and supports SQL queries. IMHO, its usage is a much simpler than with any of the other alternatives:</p>
<pre lang="matlab">
% Open the DB file
mksqlite('open', 'C:\Yair\Data\IGdb 2017-11-13.sqlite');
% Query the database
results = mksqlite(['select * from data_table where ' conditionStr]);
numericValues = [results.ID];
stringValues  = {results.Name};
% Cleanup
mksqlite('close');
</pre>
<p>Can it be any simpler than this!?<br />
However, the main benefit of <code>mksqlite</code> over the other connectors is not its simplicity but the connector&#8217;s speed. This speed is due to the fact that the query is vectorized and we do not need to loop over all the separate data rows and fields. With the other connectors, it is actually not the loop that takes so long in Matlab, but rather the overheads and inefficiencies of numerous library calls to fetch one single value at a time from the result-set &#8211; this is avoided in <code>mksqlite</code> where there is only a single call. This results in lightning speed: A couple of years ago I consulted to a client who used a JDBC connector to an SQLite database; by switching from a JDBC connector to <code>mksqlite</code>, I reduced the execution time from 7 secs to 70 msecs &#8211; a 100x speedup! In that specific case, this made the difference between an unusable program and a highly interactive/responsive one.</p>
<h3 id="alternatives">Other alternatives</h3>
<p>In addition to all the above, we can also use a <a href="http://www.codingtricks.biz/working-with-sqlite-database-in-matlab/" rel="nofollow" target="_blank">.NET-based connector</a> or a <a href="https://www.pythoncentral.io/introduction-to-sqlite-in-python/" rel="nofollow" target="_blank">Python one</a> &#8211; I leave these as an exercise for the reader&#8230;<br />
Have I forgotten some important alternative? Or perhaps you have have some related tip you&#8217;d like to share? If so, then please leave a comment below.<br />
Happy New Year everybody!</p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/using-sqlite-in-matlab">Using SQLite in Matlab</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/secure-ssl-connection-between-matlab-and-postgresql" rel="bookmark" title="Secure SSL connection between Matlab and PostgreSQL">Secure SSL connection between Matlab and PostgreSQL </a> <small>It is tricky, but quite possible, to use SSL to connect Matlab to a PostgreSQL database. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/speeding-up-matlab-jdbc-sql-queries" rel="bookmark" title="Speeding up Matlab-JDBC SQL queries">Speeding up Matlab-JDBC SQL queries </a> <small>Fetching SQL ResultSet data from JDBC into Matlab can be made significantly faster. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/matlab-toolstrip-part-5-icons" rel="bookmark" title="Matlab toolstrip – part 5 (icons)">Matlab toolstrip – part 5 (icons) </a> <small>Icons can be specified in various ways for toolstrip controls and the app window itself. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/sending-html-emails-from-matlab" rel="bookmark" title="Sending HTML emails from Matlab">Sending HTML emails from Matlab </a> <small>Matlab's sendmail only sends simple text messages by default; a simple hack can cause it to send HTML-formatted messages. ...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://undocumentedmatlab.com/articles/using-sqlite-in-matlab/feed</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
	</channel>
</rss>
