From: Young Ryu on
Hi-

I have an 3D array, A:
A(:, :, 1)=magic(5)*0.5;
A(:, :, 2)=magic(5)*1;
A(:, :, 3)=magic(5)*0.3;
A(3, 5, 2)=NaN;
A(1, 2, 2)=NaN;

I'd like to replace NaN with linearly interpolated value at Z direction. That is,
A(3, 5, 2): mean of A(3, 5, 1) and A(3, 5, 3)

I wrote a code like this:

[X Y Z]=size(A);
use1=1:Z;
for i=1:X
for j=1:Y
del1(:, 1)=A(i, j, :);
del0=~isnan(del1);
n1=interp1(use1(del0), del1(del0), use1, 'linear');
A(i, j, isnan(del1))=n1(isnan(del1));
end
end


However, I felt there would be smarter way than this time-consuming approach. Could you advise me how to do this fast? Actually, I am handling very large data, so speed is so important.

Thanks!
From: us on
"Young Ryu" <ryuyr77(a)gmail.com> wrote in message <i3heut$9q$1(a)fred.mathworks.com>...
> Hi-
>
> I have an 3D array, A:
> A(:, :, 1)=magic(5)*0.5;
> A(:, :, 2)=magic(5)*1;
> A(:, :, 3)=magic(5)*0.3;
> A(3, 5, 2)=NaN;
> A(1, 2, 2)=NaN;
>
> I'd like to replace NaN with linearly interpolated value at Z direction. That is,
> A(3, 5, 2): mean of A(3, 5, 1) and A(3, 5, 3)
>
> I wrote a code like this:
>
> [X Y Z]=size(A);
> use1=1:Z;
> for i=1:X
> for j=1:Y
> del1(:, 1)=A(i, j, :);
> del0=~isnan(del1);
> n1=interp1(use1(del0), del1(del0), use1, 'linear');
> A(i, j, isnan(del1))=n1(isnan(del1));
> end
> end
>
>
> However, I felt there would be smarter way than this time-consuming approach. Could you advise me how to do this fast? Actually, I am handling very large data, so speed is so important.
>
> Thanks!

your looping solution is hard to beat because most of the time is spent in INTERP1, which cannot be vectorized...

one of the other solutions
- slightly(!) faster for large input matrices...

m=repmat(magic(100),[1,10,3]);
m(2,2,2)=nan;
m(1,1,1)=nan;
m(1,2,2)=nan;
r=permute(m,[3,1,2]);
r=reshape(r,3,[]);
tf=~isnan(r);
for i=1:size(r,2)
r(:,i)=interp1(cx(tf(:,i)),r(tf(:,i),i),cx,'linear');
end
r=reshape(ipermute(r,[3,1,2]),size(m));

us
From: us on
On Aug 6, 8:13 pm, "us " <u...(a)neurol.unizh.ch> wrote:
> "Young Ryu" <ryuy...(a)gmail.com> wrote in message <i3heut$9...(a)fred.mathworks.com>...
> > Hi-
>
> > I have an 3D array, A:
> > A(:, :, 1)=magic(5)*0.5;
> > A(:, :, 2)=magic(5)*1;
> > A(:, :, 3)=magic(5)*0.3;
> > A(3, 5, 2)=NaN;
> > A(1, 2, 2)=NaN;
>
> > I'd like to replace NaN with linearly interpolated value at Z direction.. That is,
> > A(3, 5, 2): mean of A(3, 5, 1) and A(3, 5, 3)
>
> > I wrote a code like this:
>
> > [X Y Z]=size(A);
> > use1=1:Z;
> > for i=1:X
> >     for j=1:Y
> >         del1(:, 1)=A(i, j, :);
> >         del0=~isnan(del1);
> >         n1=interp1(use1(del0), del1(del0), use1, 'linear');
> >         A(i, j, isnan(del1))=n1(isnan(del1));
> >     end
> > end
>
> > However, I felt there would be smarter way than this time-consuming approach. Could you advise me how to do this fast? Actually, I am handling very large data, so speed is so important.
>
> > Thanks!
>
> your looping solution is hard to beat because most of the time is spent in INTERP1, which cannot be vectorized...
>
> one of the other solutions
> - slightly(!) faster for large input matrices...
>
>      m=repmat(magic(100),[1,10,3]);
>      m(2,2,2)=nan;
>      m(1,1,1)=nan;
>      m(1,2,2)=nan;
>      r=permute(m,[3,1,2]);
>      r=reshape(r,3,[]);
>      tf=~isnan(r);
> for  i=1:size(r,2)
>      r(:,i)=interp1(cx(tf(:,i)),r(tf(:,i),i),cx,'linear');
> end
>      r=reshape(ipermute(r,[3,1,2]),size(m));
>
> us- Hide quoted text -
>
> - Show quoted text -

your looping solution is hard to beat because most of the time is
spent in INTERP1, which cannot be vectorized...

one of the other solutions
- slightly(!) faster for large input matrices...


m=repmat(magic(100),[1,10,3]);
m(2,2,2)=nan;
m(1,1,1)=nan;
m(1,2,2)=nan;
r=permute(m,[3,1,2]);
r=reshape(r,3,[]);
tf=~isnan(r);
cx=(1:3).'; % <- was missing in the last reply(!)...
for i=1:size(r,2)
r(:,i)=interp1(cx(tf(:,i)),r(tf(:,i),i),cx,'linear');
end
r=reshape(ipermute(r,[3,1,2]),size(m));

us
From: Matthew Whitaker on
try this:

A(:, :, 1)=magic(5)*0.5;
A(:, :, 2)=magic(5)*1;
A(:, :, 3)=magic(5)*0.3;
A(3, 5, 2)=NaN;
A(1, 2, 2)=NaN;

%first find the NaN values
locNaN = find(isnan(A));

%covert from index to sub
[iNaN,jNaN,kNaN] = ind2sub(size(A),locNaN);

%now average in Z direction
%TO DO : add bounds check
for n = 1:numel(kNaN)
A(iNaN(n),jNaN(n),kNaN(n)) = mean(A(iNaN(n),jNaN(n),[kNaN(n)-1,kNaN(n)+1]));
end %for






"Young Ryu" <ryuyr77(a)gmail.com> wrote in message <i3heut$9q$1(a)fred.mathworks.com>...
> Hi-
>
> I have an 3D array, A:
> A(:, :, 1)=magic(5)*0.5;
> A(:, :, 2)=magic(5)*1;
> A(:, :, 3)=magic(5)*0.3;
> A(3, 5, 2)=NaN;
> A(1, 2, 2)=NaN;
>
> I'd like to replace NaN with linearly interpolated value at Z direction. That is,
> A(3, 5, 2): mean of A(3, 5, 1) and A(3, 5, 3)
>
> I wrote a code like this:
>
> [X Y Z]=size(A);
> use1=1:Z;
> for i=1:X
> for j=1:Y
> del1(:, 1)=A(i, j, :);
> del0=~isnan(del1);
> n1=interp1(use1(del0), del1(del0), use1, 'linear');
> A(i, j, isnan(del1))=n1(isnan(del1));
> end
> end
>
>
> However, I felt there would be smarter way than this time-consuming approach. Could you advise me how to do this fast? Actually, I am handling very large data, so speed is so important.
>
> Thanks!
From: Young Ryu on
us <us(a)neurol.unizh.ch> wrote in message <d8baab45-d339-4b5f-9b53-7068b29c67ab(a)q22g2000yqm.googlegroups.com>...
> On Aug 6, 8:13 pm, "us " <u...(a)neurol.unizh.ch> wrote:
> > "Young Ryu" <ryuy...(a)gmail.com> wrote in message <i3heut$9...(a)fred.mathworks.com>...
> > > Hi-
> >
> > > I have an 3D array, A:
> > > A(:, :, 1)=magic(5)*0.5;
> > > A(:, :, 2)=magic(5)*1;
> > > A(:, :, 3)=magic(5)*0.3;
> > > A(3, 5, 2)=NaN;
> > > A(1, 2, 2)=NaN;
> >
> > > I'd like to replace NaN with linearly interpolated value at Z direction. That is,
> > > A(3, 5, 2): mean of A(3, 5, 1) and A(3, 5, 3)
> >
> > > I wrote a code like this:
> >
> > > [X Y Z]=size(A);
> > > use1=1:Z;
> > > for i=1:X
> > >     for j=1:Y
> > >         del1(:, 1)=A(i, j, :);
> > >         del0=~isnan(del1);
> > >         n1=interp1(use1(del0), del1(del0), use1, 'linear');
> > >         A(i, j, isnan(del1))=n1(isnan(del1));
> > >     end
> > > end
> >
> > > However, I felt there would be smarter way than this time-consuming approach. Could you advise me how to do this fast? Actually, I am handling very large data, so speed is so important.
> >
> > > Thanks!
> >
> > your looping solution is hard to beat because most of the time is spent in INTERP1, which cannot be vectorized...
> >
> > one of the other solutions
> > - slightly(!) faster for large input matrices...
> >
> >      m=repmat(magic(100),[1,10,3]);
> >      m(2,2,2)=nan;
> >      m(1,1,1)=nan;
> >      m(1,2,2)=nan;
> >      r=permute(m,[3,1,2]);
> >      r=reshape(r,3,[]);
> >      tf=~isnan(r);
> > for  i=1:size(r,2)
> >      r(:,i)=interp1(cx(tf(:,i)),r(tf(:,i),i),cx,'linear');
> > end
> >      r=reshape(ipermute(r,[3,1,2]),size(m));
> >
> > us- Hide quoted text -
> >
> > - Show quoted text -
>
> your looping solution is hard to beat because most of the time is
> spent in INTERP1, which cannot be vectorized...
>
> one of the other solutions
> - slightly(!) faster for large input matrices...
>
>
> m=repmat(magic(100),[1,10,3]);
> m(2,2,2)=nan;
> m(1,1,1)=nan;
> m(1,2,2)=nan;
> r=permute(m,[3,1,2]);
> r=reshape(r,3,[]);
> tf=~isnan(r);
> cx=(1:3).'; % <- was missing in the last reply(!)...
> for i=1:size(r,2)
> r(:,i)=interp1(cx(tf(:,i)),r(tf(:,i),i),cx,'linear');
> end
> r=reshape(ipermute(r,[3,1,2]),size(m));
>
> us

Your code was significantly faster than my code. In my large array dataset, my code took 180 sec, and your code took 49 sec! Could you advise me in which part your code could reduce the process time? Probably, using for loop one time (your code) makes faster than using for loop two times (my code)?

Thank you so much