smooth2a.m 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. function matrixOut = smooth2a(matrixIn,Nr,Nc)
  2. % Smooths 2D array data. Ignores NaN's.
  3. %
  4. %function matrixOut = smooth2a(matrixIn,Nr,Nc)
  5. %
  6. % This function smooths the data in matrixIn using a mean filter over a
  7. % rectangle of size (2*Nr+1)-by-(2*Nc+1). Basically, you end up replacing
  8. % element "i" by the mean of the rectange centered on "i". Any NaN
  9. % elements are ignored in the averaging. If element "i" is a NaN, then it
  10. % will be preserved as NaN in the output. At the edges of the matrix,
  11. % where you cannot build a full rectangle, as much of the rectangle that
  12. % fits on your matrix is used (similar to the default on Matlab's builtin
  13. % function "smooth").
  14. %
  15. % "matrixIn": original matrix
  16. % "Nr": number of points used to smooth rows
  17. % "Nc": number of points to smooth columns. If not specified, Nc = Nr.
  18. %
  19. % "matrixOut": smoothed version of original matrix
  20. %
  21. %
  22. % Written by Greg Reeves, March 2009.
  23. % Division of Biology
  24. % Caltech
  25. %
  26. % Inspired by "smooth2", written by Kelly Hilands, October 2004
  27. % Applied Research Laboratory
  28. % Penn State University
  29. %
  30. % Developed from code written by Olof Liungman, 1997
  31. % Dept. of Oceanography, Earth Sciences Centre
  32. % G?teborg University, Sweden
  33. % E-mail: olof.liungman@oce.gu.se
  34. %
  35. % Initial error statements and definitions
  36. %
  37. if nargin < 2, error('Not enough input arguments!'), end
  38. N(1) = Nr;
  39. if nargin < 3, N(2) = N(1); else N(2) = Nc; end
  40. if length(N(1)) ~= 1, error('Nr must be a scalar!'), end
  41. if length(N(2)) ~= 1, error('Nc must be a scalar!'), end
  42. %
  43. % Building matrices that will compute running sums. The left-matrix, eL,
  44. % smooths along the rows. The right-matrix, eR, smooths along the
  45. % columns. You end up replacing element "i" by the mean of a (2*Nr+1)-by-
  46. % (2*Nc+1) rectangle centered on element "i".
  47. %
  48. [row,col] = size(matrixIn);
  49. eL = spdiags(ones(row,2*N(1)+1),(-N(1):N(1)),row,row);
  50. eR = spdiags(ones(col,2*N(2)+1),(-N(2):N(2)),col,col);
  51. %
  52. % Setting all "NaN" elements of "matrixIn" to zero so that these will not
  53. % affect the summation. (If this isn't done, any sum that includes a NaN
  54. % will also become NaN.)
  55. %
  56. A = isnan(matrixIn);
  57. matrixIn(A) = 0;
  58. %
  59. % For each element, we have to count how many non-NaN elements went into
  60. % the sums. This is so we can divide by that number to get a mean. We use
  61. % the same matrices to do this (ie, "eL" and "eR").
  62. %
  63. nrmlize = eL*(~A)*eR;
  64. nrmlize(A) = NaN;
  65. %
  66. % Actually taking the mean.
  67. %
  68. matrixOut = eL*matrixIn*eR;
  69. matrixOut = matrixOut./nrmlize;