Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>First of all, you can skip the matrix <code>m</code>. It is a less-than-optimal way to go about the problem in this case. Also, get rid of the zeros at the end of <code>x_t</code>. They are not necessary. If you need help trimming the zeros off the end, try this:</p> <pre><code>x_t = x_t(1:find(x_t~=0,1,'last')); </code></pre> <p>Now, for the matching. You can find the closest match in <code>x_t</code> to the elements of <code>x</code> with the following:</p> <pre><code>B = bsxfun(@minus, x_t(:), x(:).'); %' [idx,~] = find(bsxfun(@eq, abs(B), min(abs(B)))); y = x_t(idx); </code></pre> <p>Now the approximations of <code>x</code> are found in <code>y</code>, with corresponding index found in <code>idx</code>.</p> <h1>Explanation</h1> <hr> <pre><code>bsxfun(@minus, x, y); </code></pre> <p>This will take a column vector <code>x</code> and subtract it by the each or the elements of the row vector <code>y</code>. For example,</p> <pre><code>&gt;&gt; x = [3 6 9 12].'; y = [1 2 3]; &gt;&gt; ans = bsxfun(@minus, x, y); ans = 2 1 0 5 4 3 8 7 6 11 10 9 </code></pre> <p>Or in other words, what is happening is:</p> <p>ans = </p> <pre><code> (3-1) (3-2) (3-3) (6-1) (6-2) (6-3) (9-1) (9-2) (9-3) (12-1) (12-2) (12-3) </code></pre> <hr> <pre><code>bsxfun(@eq, A, min(A)); </code></pre> <p>This finds the locations in the columns of the matrix <code>A</code> where the column minimum resides. It returns a logical matrix (ones and zeros). For example,</p> <pre><code>&gt;&gt; A = [ 1 2 3 4; 3 3 6 5; 2 2 0 7; 5 1 8 5; 4 5 2 6]; &gt;&gt; ans = bsxfun(@eq, A, min(A)) ans = 1 0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 </code></pre> <hr> <pre><code>[idx,~] = find(A); </code></pre> <p>The <code>find</code> command searches for all of the non-zero elements of the matrix <code>A</code>. Normally you would call it as <code>[row, col] = find(A);</code> to get back the rows and columns, but since I am only interested in the row, I use <code>~</code> to tell Matlab that I don't want to keep the column value.</p> <hr> <pre><code>y = x(idx); </code></pre> <p>This creates a new vector <code>y</code> which contains the elements of <code>x</code> as referenced by <code>idx</code>. Since I already found the indices that minimize the error, I use them to pluck out the <code>x</code> values at those indices.</p> <hr> <p><strong>Putting it all together:</strong></p> <p>At a high level, the code does the following:</p> <p><li> The matrix <code>B</code> compares every value of <code>x</code> (columns) with every value of <code>x_t</code> (rows) <li> For every column (<code>x</code>) of <code>B</code>, find the row (<code>x_t</code>) which minimizes the error. <li> Knowing the rows we can extract the <code>x_t</code> values directly using the row indices.</p> <p>Hope this helps!</p> <h1>Update</h1> <p>I realized that if a value of <code>x</code> was exactly the same distance between two values of <code>x_t</code> then you would end up with a vector that was too long, because multiple answers will be selected. Below is the fix to the problem.</p> <pre><code>B = bsxfun(@minus, x_t(:), x(:).'); %' [idx,col] = find(bsxfun(@eq, abs(B), min(abs(B)))); idx(1 &lt; sum(triu(bsxfun(@eq, col(:), col(:).')))) = []; %' y = x_t(idx); </code></pre> <p>Basically what the added line does is throw away any index values that do not correspond to the first match in a given column.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload