From: Conrad on
Hi all

Consider the matrix A as an example

A =

0 0 0 0 2 4 6 8 0 0
0 0 0 3 4 5 0 0 0 0
0 0 0 0 0 0 2 4 0 0

In general A will be a mxn matrix with strictly increasing values (except for the zeros) in each row. For every row of the matrix A I want to change the non-zero values to the value of the very first non-zero entry in that particular row, i.e. our example becomes

A =

0 0 0 0 2 2 2 2 0 0
0 0 0 3 3 3 0 0 0 0
0 0 0 0 0 0 2 2 0 0

My current solution:
-------------------------------------------
[d1 d2] = size(A);
B = A;
B(B==0) = NaN;
minValues = repmat(min(B, [], 2),1,d2);
A = (A~=0).*minValues;

which gives the desired result.

Is there a better/more elegant way of doing this?

Regards
Conrad
From: Matt J on
"Conrad " <cvisagie(a)riscura.com> wrote in message <hilgfj$dfk$1(a)fred.mathworks.com>...
> Hi all
>
> Consider the matrix A as an example
>
> A =
>
> 0 0 0 0 2 4 6 8 0 0
> 0 0 0 3 4 5 0 0 0 0
> 0 0 0 0 0 0 2 4 0 0
>
> In general A will be a mxn matrix with strictly increasing values (except for the zeros) in each row. For every row of the matrix A I want to change the non-zero values to the value of the very first non-zero entry in that particular row, i.e. our example becomes
>
> A =
>
> 0 0 0 0 2 2 2 2 0 0
> 0 0 0 3 3 3 0 0 0 0
> 0 0 0 0 0 0 2 2 0 0
>
> My current solution:
> -------------------------------------------
> [d1 d2] = size(A);
> B = A;
> B(B==0) = NaN;

Best to use Inf as opposed to NaN


> minValues = repmat(min(B, [], 2), 1,d2);
> A = (A~=0).*minValues;

If you have bsxfun, there's no need for the extra memory alloc of repmat, nor is there a need for multiplication ops:

minValues=min(B, [], 2);
A=bsxfun(@min,A,minValues);
From: Matt Fig on
This should be fairly fast.


B = A>0;
[k,k] = max(B,[],2);
A = bsxfun(@times,B,A((1:m)'+(k-1)*size(A,1)));
From: Jos (10584) on
"Conrad " <cvisagie(a)riscura.com> wrote in message <hilgfj$dfk$1(a)fred.mathworks.com>...
> Hi all
>
> Consider the matrix A as an example
>
> A =
>
> 0 0 0 0 2 4 6 8 0 0
> 0 0 0 3 4 5 0 0 0 0
> 0 0 0 0 0 0 2 4 0 0
>
> In general A will be a mxn matrix with strictly increasing values (except for the zeros) in each row. For every row of the matrix A I want to change the non-zero values to the value of the very first non-zero entry in that particular row, i.e. our example becomes
>
> A =
>
> 0 0 0 0 2 2 2 2 0 0
> 0 0 0 3 3 3 0 0 0 0
> 0 0 0 0 0 0 2 2 0 0
>
> My current solution:
> -------------------------------------------
> [d1 d2] = size(A);
> B = A;
> B(B==0) = NaN;
> minValues = repmat(min(B, [], 2),1,d2);
> A = (A~=0).*minValues;
>
> which gives the desired result.
>
> Is there a better/more elegant way of doing this?
>
> Regards
> Conrad

Given that A is strictly increasing you could avoid the min:

A = [ 0 0 0 0 2 4 6 8 0 0
0 0 0 3 4 5 0 0 0 0
0 0 0 0 0 0 2 4 0 0] ;

Q = double(A ~= 0) ;
B = cumsum(A .* (cumsum(Q,2)==1),2) .* Q

which might be improved upon.

hth
Jos