Wednesday, December 22, 2010

num2strcell

function mystrcel=num2strcell(mynum,GFmat)
% to convert a numeric array into a string cell
% usage:
%           mystrcel=num2strcell(YouNumArray,Digit.Format);
%  e.g.,  mystrcel=num2strcell(0.1:0.1:0.5,'%3.2f');
%  copyright by http://scriptdemo.blogspot.com

[nrow,ncol]=size(mynum);
for nj=1:nrow
      for ni=1:ncol
            mystrcel{nj,ni}=num2str(mynum(nj,ni),GFmat);
      end
end

read netcdf file using native matlab functions

UPDATED VERSION:  Here

function ncvardata=GetNcVarMatlab(ncfile,ncvar,RangeStr)
% to read data from the netcdf file using native matlab netcdf-functions
% Usage: vardata=GetNcVarMatlab(nc-filename,nc-varname,Dimension-Range)
% e.g.,
% mydata=GetNcVarMatlab('mask.nc','tmask','1:1,1:46,1:400,1:568');
% RangeStr here is similar to the output of ncdump
% copyright by http://scriptdemo.blogspot.com

IsDebug=0;
if ~exist(ncfile,'file')
   error([ncfile,' can not been found']);
   return
end

ncfid=netcdf.open(ncfile,'NC_NOWRITE');
% get dimension length
[numdims, numvars, numglobalatts, unlimdimID] = netcdf.inq(ncfid);
for NDim=1:numdims
      [dimname{NDim}, dimlen(NDim)] = netcdf.inqDim(ncfid,NDim-1);
end

%var infor
varid=netcdf.inqVarID(ncfid,ncvar);
[varname,varxtype,vardimids,varnumatts]=netcdf.inqVar(ncfid,varid);
numdims=length(vardimids); % some variables may have less dimensions

if ~exist('RangeStr','var')
   RangeStr=':';
   for nd=2:numdims
         RangeStr=[RangeStr,',:'];
   end
end

IndC=strfind(RangeStr,',');% index of commas
if length(IndC)~=numdims-1
   disp(['Input dimension range is not correct, should be: ',num2str(numdims),'-d']);
   return
end

startstr=''; countstr=''; stridestr='';
for nn=1:length(IndC)+1
      if nn==1
         tmpstr=RangeStr(1:IndC(1)-1);
      elseif nn<numdims
         tmpstr=RangeStr(IndC(nn-1)+1:IndC(nn)-1);
      else
         tmpstr=RangeStr(IndC(nn-1)+1:end);
      end

      [tmpstart,tmpcount,tmpstride]=GetIndFromStr(tmpstr,':',dimlen(vardimids(numdims-nn+1)+1));
     if nn==1
        startstr=[num2str(tmpstart),'],'];
        countstr=[num2str(tmpcount),'],'];
        stridestr=[num2str(tmpstride),']'];
     elseif nn==numdims
        startstr=[',[',num2str(tmpstart),',',startstr];
        countstr=['[',num2str(tmpcount),',',countstr];
        stridestr=['[',num2str(tmpstride),',',stridestr];
     else
        startstr=[num2str(tmpstart),',',startstr];
        countstr=[num2str(tmpcount),',',countstr];
        stridestr=[num2str(tmpstride),',',stridestr];
     end
end

if IsDebug
   disp(['ncvardata=netcdf.getVar(ncfid,varid',startstr,countstr,stridestr,');']);
end
eval(['ncvardata=netcdf.getVar(ncfid,varid',startstr,countstr,stridestr,');']);
netcdf.close(ncfid);
ncvardata=permute(ncvardata,length(size(ncvardata)):-1:1);

function [numstart,numcount,numstride]=GetIndFromStr(tmpstr,ctag,Ndim)
% Read the numbers from the special string
IsDebug=0;
IndC=strfind(tmpstr,ctag);
if isempty(IndC)
   numstart=str2double(tmpstr)-1;
   numcount=1;
   numstride=1;
else
  switch length(IndC)
    case {1}
        switch IndC
            case {1} % : and :num
                if strcmp(tmpstr,':')
                   numstart=0; numcount=Ndim; numstride=1;
                else
                   if strcmp(tmpstr(2:end),'end')
                      numstart=0; numcount=Ndim; numstride=1;
                   else
                      numstart=0; numcount=str2double(tmpstr(2:end))-1; numstride=1;
                   end
                end
            case {length(tmpstr)}
                if strcmp(tmpstr,':')
                    numstart=0; numcount=Ndim; numstride=1;
                    return
                else
                    numstart=str2double(tmpstr(1:IndC-1))-1;
                    numcount=Ndim-numstart;
                    numstride=1;
                end
           otherwise
                numstart=str2double(tmpstr(1:IndC-1))-1;
                if strcmp(tmpstr(IndC+1:end),'end')
                    numend=Ndim;
                else
                    numend=str2double(tmpstr(IndC+1:end));
                end
                numcount=numend-numstart;
                numstride=1;
            end
   case {2}
      % num0:stride:num1
      if IndC(1)==1
         numstart=0;
      else
         numstart=str2double(tmpstr(1:IndC(1)-1))-1;
      end
      if IndC(2)==IndC(1)+1
         numstride=1;
      else
         numstride=str2double(tmpstr(IndC(1)+1:IndC(2)-1));
      end
      if IndC(2)==length(tmpstr)
             numend=Ndim;
      else
         if strcmp(tmpstr(IndC(2)+1:end),'end')
            numend=Ndim;
         else
            numend=str2double(tmpstr(IndC(2)+1:end));
         end
      end
      numcount=numend-numstart;
   otherwise
       error('Not defined range type')
   end
end
if IsDebug
   disp(['tmpstr=',tmpstr])
   disp(['start:',num2str(numstart), ' stride:',num2str(numstride),' count:',num2str(numcount)])
end

Friday, December 17, 2010

Visualize Julia Sets using Matlab

function myjulia(Zmax,c,N)
% Generate and visualize quadratic Julia Sets
% More information about Julia Sets can be found here:
% http://en.wikipedia.org/wiki/Julia_set
% this code is for the assignment of the "Introduction to Matlab" offered by MITOPENCOURSEWARE
% Coded by http://scriptdemo.blogspot.com

if (nargin==1)
   Ndemo=Zmax; clear Zmax
   switch Ndemo
   case {1}
       myjulia(1,-0.297491+i*0.641051,100);
       return;
   case {2}
       myjulia(0.35,-0.297491+i*0.641051,250);
       return;
   otherwise
      disp('Not defined demo type!')
      help myjulia;
      return
   end
elseif (nargin~=3)
   help myjulia;
   return
end

% generate the basic matrix
NM=500;
[Z,tmpy]=meshgrid(linspace(-Zmax,Zmax,NM),zeros(1,NM));
Z=Z+i*Z'; clear tmpy

% compute the escape velocity
myM=reshape(escapeVelocity(Z(:),c,N),NM,NM);

% visualize the results
imagesc(atan(0.1*myM)); figurenicer;axis xy;

function n=escapeVelocity(z0,c,N)
n=z0*0;
NLen=length(z0);
IndZ=1:length(z0);
IndZ=IndZ';
for ni=1:N
      IndLT=find(abs(z0)<2);
      IndGE=find(abs(z0)>=2);
      n(IndZ(IndGE))=ni;
      if (length(IndLT)>0)
         z0(IndLT)=z0(IndLT).*z0(IndLT)+c;
      end
      z0(IndGE)=[];
      IndZ(IndGE)=[];
end
if ~isempty(IndZ)
   n(IndZ)=N;
end
myjulia(2)

Generate a series of column names in R

#if you want a series of column names, e.g., col1,col2,col3, ...,
#you can use:
mydf<-data.frame(matrix(ncol=5,nrow=4))
colnames(mydf)<-c("col1","col2","col3","col4","col5")
#Well, it does work, but how about for 50 columns?
#A loop! Sounds great. Okay,
mydf<-data.frame(matrix(ncol=50,nrow=4))
for (n in 1:ncol(mydf))
{
      colnames(mydf)[n]<-paste("col",n,sep="")
}
#But again, it's as urgly as the textbook. Here we offer a much better solution:
colnames(mydf)<-paste(rep("col",ncol(mydf)),c(1:ncol(mydf)),sep="")
#Smart, eh? At least the nicer looking :)
#From http://scriptdemo.blogspot.com

Trim a string in R

# sub-functions
# Copyright: http://scriptdemo.blogspot.com
mytrim<-function(oristr)
{
     oristr<-sub("^ +","",oristr)
     oristr<-sub(" +$","",oristr)
     # or gsub("(^ +)|( +$)","",oristr)
     return(oristr)
}

Wednesday, November 17, 2010

Run matlab m-file in a shell script

It is common to run Matlab without splash and desktop using the following command,
        matlab -nosplash -nodesktop
Sometime the "-nojvm" option also help to reduce the memory requires if the java-virtual-mathine features are not necessary in your script.

But, what should we do if we want to run a Matlab m-file in a shell script? The only thing we need is the option of "-r",

        matlab -nosplash -nodesktop -r YourMFile

However, sometimes it will be much more convenient if we can run the function-type m-file with arguments. Here it comes today's tricky stuff:       
        matlab -nodesktop -nosplash -r YourMFile\(Number,\'character\'\)
Matlab Start Help 

Here is an example,
runMatlabScript.sh

#!/bin/bash
myNum=30
myT="Demo\ of\ Peaks\(${myNum}\)"
myPNG="fig_peaks_${myNum}"
eval "/media/SW_Preload/matlab/bin/matlab -nodesktop -nosplash -r showPeaks\(${myNum},\'${myT}\',\'${myPNG}\'\)"
showPeaks.m:
function showPeaks(myN,myTitle,myPNG)
% show the the peaks
% usage:
%           showPeaks(N,Title,FileName)
%           http://scriptdemo.blogspot.ca

if nargin~=3
   disp('Usage: ')
   disp(' showPeaks(N,Title,FileName) ')
   return
end

hf=figure('visible','off');
set(hf,'color','w','render','zbuffer');
hp=pcolor(peaks(myN));
set(hp,'linestyle','none');
title(myTitle,'fontweight','bold','fontsize',16);
set(gca,'linewidth',2)
eval(['print -dpng -r300 ',myPNG,'.png'])
close;
exit

Saturday, October 23, 2010

An example of image processing using matlab

function [imgdatadb,mymask]=rgb2whiteblack(ImgFileName,mymask)
%  To show some basic image processing (percentage of some colors)
%  using matlab. Also shows how to create a mask using mouse.
%  Copyright: http://scriptdemo.blogspot.com
IsFig=0; IsFinalFig=1;
% read image
if nargin==0
    ImgFileName='8x.JPG';
end
if ~exist(ImgFileName,'file')
    disp(['image file: ',ImgFileName,' cannot be found!!! return nothing'])
    imgdatadb=[];mymask=[];
    return
end

% assume input image is in rgb mode
imgrgb=imread(ImgFileName);

% Be more accurate or professional, consider operations with rgb channels
if ~exist('mymask','var')
   %create the mask
   mask1=roipoly(imgrgb);
   mask2=roipoly(imgrgb);
   mask3=roipoly(imgrgb);
   mymask=mask1+mask2+mask3;
   close;
end

if IsFig % show rgb channels of the image
   figure;
   for N=1:4
       subplot(2,2,N);
       if N~=4
          imagesc(imgrgb(:,:,N));
       else
          imagesc(imgrgb);
       end
   end
end

% convert data into gray scale [intensity image]
imgdata=rgb2gray(imgrgb); % or maybe consider rgb2bw
%convert to double
imgdatadb=double(imgdata);

% convert dark part to black
imgdatadb(imgdatadb<100)=0;
% ..      light part to white
imgdatadb(imgdatadb>=100)=255;
% set mask region to specified value, e.g., 90
imgdatadb(mymask==1)=90;

% statistics
NumOfMaskP=length(find(mymask==1));
NumOfEffectiveP=length(imgdatadb(:))-NumOfMaskP;
PerEffective=NumOfEffectiveP/(NumOfMaskP+NumOfEffectiveP)*100;
PerBlack=length(find(imgdatadb==0))/NumOfEffectiveP*100;

% show percentage
disp(['Percentage of Effective  pixels (%): ',num2str(PerEffective)])
disp(['Percentage of black region (%): ',num2str(PerBlack)])

% show image
if IsFinalFig
   figure;
   title('Origin Gray image');imagesc(imgdata);
   figure;
   title('Black and White'); imagesc(uint8(imgdatadb));
end

Wednesday, October 13, 2010

Plot a heart curve in matlab

 
function ShowHeart(Ntype)
% a funny script to show different kind of heart curves
% Usage:
%        ShowHeart()
% Copyright: http://scriptdemo.blogspot.com
% Ref: http://www.mathematische-basteleien.de/heart.htm
%        http://mathworld.wolfram.com/HeartCurve.html

if nargin==0 Ntype=1; end

np=999;Is3D=0;IsFilled=1;
switch Ntype
    case {1}
       t=0:2*pi/np:2*pi;
       xx=(1-sin(t)).*cos(t);
       yy=(1-sin(t)).*sin(t);
    case {2}
       t=-1:2/(np*100):1;
       xx=sin(t).*cos(t).*log(abs(t));
       yy=sqrt(cos(t)).*abs(t).^0.3;
       yy(isnan(xx))=[];
       xx(isnan(xx))=[];
    case {3}
       t=-1:2/(np*100):1;
       xx=sin(t).*cos(t).*log(abs(t));
       yy=sqrt(abs(t)).*cos(t);
       yy(isnan(xx))=[];
       xx(isnan(xx))=[];
    case {4}
       t=0:2*pi/np:2*pi;
       r=sin(t).*sqrt(abs(cos(t)))./(sin(t)+7/5)-2*sin(t)+2;
       xx=r.*cos(t); yy=r.*sin(t); clear r
    case {5}
       t=0:60/np:60;
       r=0.01*(-t.*t+40*t+1200);
       xx=r.*sin(pi*t/180);
       yy=r.*cos(pi*t/180); clear r t
       xx=[xx fliplr(-xx)]; yy=[yy fliplr(yy)];
    case {6}
       t=-1:2/(np*100):1;
       r=(1-abs(t)).*(1+3*abs(t));
       xx=r.*sin(t); yy=r.*cos(t); clear r t
    otherwise
       disp(['Sorry, you just broke my heart!']);
       Is3D=1;
       t=0:2*pi/np:2*pi;
       r=sin(t).*sqrt(abs(cos(t)))./(sin(t)+7/5)-2*sin(t)+2;
       xx=r.*cos(t); yy=r.*sin(t); clear r
end
if ~Is3D
   if ~IsFilled
      plot(xx,yy,'color','r');
   else
      hf=fill(xx,yy,'r');set(hf,'linestyle','none');
   end
else
  hp=plot(xx,yy,'g');set(hp,'linestyle','none');
  figurenicer; hold on;
  myxlim=xlim;myylim=ylim;
  nrp=50;
  nxgrid=20;
  nygrid=20;
  xxn=linspace(myxlim(1),myxlim(2),nxgrid);
  yyn=linspace(myylim(1),myylim(2),nygrid);
  [xxn,yyn]=meshgrid(xxn,yyn);
  tmprand=randn(nrp,2);
  tmprand=tmprand/max(abs(tmprand(:)))/2;
  xxrand=zeros(nrp,nxgrid*nygrid);
  yyrand=xxrand;
  np=1;
  for Nx=1:nxgrid
      for Ny=1:nygrid
         xxrand(:,np)=xxn(Ny,Nx)+tmprand(:,1);
         yyrand(:,np)=yyn(Ny,Nx)+tmprand(:,2);
         np=np+1;
      end
  end
  Ind=inpolygon(xxn(:),yyn(:),xx(:),yy(:));
  tmpind=1:length(xxn(:));
  [jj,ii]=ind2sub(size(xxn),tmpind(Ind==1));
  Ind2=sub2ind(size(xxn),jj(:)+1,ii(:));
  Ind=sub2ind(size(xxn),jj(:),ii(:));
  xxrand(:,Ind2)=xxrand(:,Ind);
  yyrand(:,Ind2)=yyrand(:,Ind);
  
  [xxnew,yynew]=GetRandom(xx(:),yy(:),5);
  hp0=plot(xxnew,yynew,'g.');set(hp0,'linestyle','none','markersize',1);
  %plot(xxn(:),yyn(:),'.b');
  hp=plot(xxrand,yyrand,'.g');set(hp,'linestyle','none','markersize',1);
end
figurenicer;
axis equal;
axis tight;
function [xxnew,yynew]=GetRandom(xx,yy,nrp)
 np=length(xx);
 if (np>360)
    iii=linspace(1,np,360);
    iii=fix(iii);
    xx=xx(iii); yy=yy(iii);
    np=length(xx);
 end
 tmprand=randn(nrp,2);
 tmprand=tmprand/max(abs(tmprand(:)))*8;
 xxnew=zeros(nrp,length(xx));
 xx=reshape(xx,1,[]);
 yy=reshape(yy,1,[]);
 xxdif=diff(xx);xxdif=[xxdif(1) xxdif];
 yydif=diff(yy);yydif=[yydif(1) yydif];
 for N=2:length(xx)
     xxnew(:,N)=0.5*(xx(N-1)+xx(N))+tmprand(:,1)*xxdif(N);
     yynew(:,N)=0.5*(yy(N-1)+yy(N))+tmprand(:,2)*yydif(N);
 end
xxnew(:,1)=xxnew(:,2);
yynew(:,1)=yynew(:,2);

Thursday, September 30, 2010

Fortran Code dealing with longitude

! Copyright by http://scriptdemo.blogspot.com
MODULE  mod_longcheck
  USE mod_precision
  IMPLICIT NONE
CONTAINS
  FUNCTION Check180(mylon)
   ! check whether it is close to the International Date Line (IDL)
   logical                    :: Check180
   real(kind=rprec)           :: mylon

   if ( abs(abs(mylon)-180.0) < 15.0) then
   ! here the threshold value is arbitrary
      Check180=.TRUE.
   else
      Check180=.FALSE.
   endif
  END FUNCTION Check180

  FUNCTION CheckZero(mylon)
   ! check if whether it is close to the Primary Line
   logical                    :: CheckZero
   real(kind=rprec)           :: mylon

   if ( abs(mylon) < 5.0) then
   ! here the threshold value is arbitrary
      CheckZero=.TRUE.
   else
      if (abs(abs(mylon)-360.0)< 5.) then
         CheckZero=.TRUE.
      else
         CheckZero=.FALSE.
      endif
   endif
  END FUNCTION CheckZero

  FUNCTION Back180(mylon)
  ! convert a longitude into a range of [-180 180]
   real(kind=rprec)   :: mylon
   real(kind=rprec)   :: Back180

   Back180=mylon
   if (Back180<0.0) then
      do while (Back180 < -180.0)
         Back180=Back180+360.0
      enddo
   else
     do while (Back180>180.0)
         Back180=Back180-360.0
     enddo
   endif
   return
  END FUNCTION Back180
  FUNCTION Back360(mylon)
  ! convert a longitude into a range of [0 360]
   real(kind=rprec)   :: mylon
   real(kind=rprec)   :: Back360
  
   Back360=mylon
   if (Back360<0.0) then
      do while (Back360 < 0.0)
          Back360=Back360+360.0
      enddo
   else
      do while (Back360>360.0)
        Back360=Back360-360.0
      enddo
   endif
   return
  END FUNCTION Back360
  SUBROUTINE ll2xy(mylon,mylat,myx,myy)
   ! convert given long/latitude into x/y in stereographic projection
   real(kind=rprec)   :: mylon,mylat
   real(kind=rprec)   :: myx,myy
   ! local variables
   real(kind=rprec)               :: mypi,deg2r,myphi,mylam
   real(kind=rprec)               :: rho,Re,phi0,lam0
   real(kind=rprec)               :: a,b,k,f,e,e2,e4,e6,t
  
   Re=6371000.0          ! the earth radius
   mypi=acos(-1.0)
   deg2r=mypi/180.0
   myphi=mylat*deg2r
   mylam=mylon*deg2r
   phi0=0.
   lam0=0.
  

   if (mylat>84.0) then
     rho=2.0*Re*(sqrt((1.0-sin(myphi))/(1.0+sin(myphi))))
     myx=rho*sin(mylam-lam0)
     myy=-rho*cos(mylam-lam0)
     myx=myx+2000000.0
     myy=myy+2000000.0
   elseif (mylat<-84.0) then
     ! south-hemisphere stereographic projection
     myphi=-myphi
     mylam=-mylam
     lam0=-lam0
    
     rho=2.0*Re*(sqrt((1.0-sin(myphi))/(1.0+sin(myphi))))
     myx=rho*sin(mylam-lam0)
     myy=-rho*cos(mylam-lam0)
     myx=-myx; myy=-myy
     myx=myx+2000000.0
     myy=myy+2000000.0
   else
      stop "NOT DEFINED YET, maybe just not necessary"
  endif
  END SUBROUTINE ll2xy
  SUBROUTINE xy2ll(myx,myy,mylon,mylat)
   ! convert given x/y in the stereographic projection into long/latitude
   real(kind=rprec)    :: myx,myy
   real(kind=rprec)   :: mylon,mylat
   ! local variables
   real(kind=rprec)               :: mypi,deg2r,myphi,mylam,lat0
   real(kind=rprec)               :: xx,yy
   real(kind=rprec)               :: rho,Re,phi0,lam0
   real(kind=rprec)               :: a,b,k,f,e,e2,e4,e6,t

   mypi=acos(1.0)
   deg2r=mypi/180.0
   Re=6371000.0
  
   lam0=0.0
   phi0=0.0
   lat0=90.0

   if (lat0>84.0) then
     xx=myx-2000000.0
     yy=myy-2000000.0
     rho = sqrt (xx*xx + yy*yy)
 
     myphi=mypi*0.5-2*atan(0.5*rho/Re)
     mylam=lam0+atan2(xx,-yy)
   elseif (lat0<-84.0) then
     stop 'Should not see this msg'
     xx=-(myx-2000000.0)
     yy=-(myy-2000000.0)
     rho=sqrt(xx*xx+yy*yy)
     myphi=0.5*mypi-2*atan(0.5*rho/Re)
     myphi=-myphi
     mylam=-(-lam0+atan2(xx,-yy))
   else
     stop 'Should not see this msg'
   endif
  
  END SUBROUTINE xy2ll
END MODULE mod_longcheck

Saturday, September 25, 2010

Pack netcdf file

#!/bin/bash
# A simple usage of ncpdq from nco (http://nco.sourceforge.net)
# Please check more details from the nco website.
#   Usage:  packnc.sh myncfile(s)
#   NOTE: There will be a loss of precision in type conversion
#         (converted to short by default)
# Copyright by http://scriptdemo.blogspot.com/
 
IsNCPDQ=`which ncpdq`
if [ ${#IsNCPDQ} -eq 0 ]; then
   echo "ncpdq can not be found in the path..."
   echo "Please double check your NetCDF Operator (NCO) Path"
   exit
fi

if [ $# -eq 0 ]; then
   sed -n '4p' packnc.sh
   exit
else
   Nfiles=$*
   for ncfile in ${Nfiles}
   do
      [ -f ${ncfile} ] && ncpdq -P all_xst ${ncfile}  tmpout_${ncfile} && mv tmpout_${ncfile} ${ncfile}
   done
fi

Wednesday, August 11, 2010

Arrays in Bash

#!/bin/bash
#
# Usage:
#       FileNameMon.sh nmon
# Copyright by http://scriptdemo.blogspot.com
if [ $# -ne 1 ]; then
   sed -n '3,4p' FileNameMon.sh
   exit
fi
case $1 in
 1)
   fnarray[0]="m01d05"
   fnarray[1]="m01d10"
   fnarray[2]="m01d15"
   fnarray[3]="m01d20"
   fnarray[4]="m01d25"
   fnarray[5]="m01d30"
   ;;
 2)
   fnarray[0]="m02d04"
   fnarray[1]="m02d09"
   fnarray[2]="m02d14"
   fnarray[3]="m02d19"
   fnarray[4]="m02d24"
   fnarray[5]="m03d01"
   ;;
 3)
   fnarray[0]="m03d06"
   fnarray[1]="m03d11"
   fnarray[2]="m03d16"
   fnarray[3]="m03d21"
   fnarray[4]="m03d26"
   fnarray[5]="m03d31"
   ;;
 4)
   fnarray[0]="m04d05"
   fnarray[1]="m04d10"
   fnarray[2]="m04d15"
   fnarray[3]="m04d20"
   fnarray[4]="m04d25"
   fnarray[5]="m04d30"
   ;;
 5)
   fnarray[0]="m05d05"
   fnarray[1]="m05d10"
   fnarray[2]="m05d15"
   fnarray[3]="m05d20"
   fnarray[4]="m05d25"
   fnarray[5]="m05d30"
   ;;
 6)
   fnarray[0]="m06d04"
   fnarray[1]="m06d09"
   fnarray[2]="m06d14"
   fnarray[3]="m06d19"
   fnarray[4]="m06d24"
   fnarray[5]="m06d29"
   ;;
 7)
   fnarray[0]="m07d04"
   fnarray[1]="m07d09"
   fnarray[2]="m07d14"
   fnarray[3]="m07d19"
   fnarray[4]="m07d24"
   fnarray[5]="m07d29"
   ;;
 8)
   fnarray[0]="m08d03"
   fnarray[1]="m08d08"
   fnarray[2]="m08d13"
   fnarray[3]="m08d18"
   fnarray[4]="m08d23"
   fnarray[5]="m08d28"
   fnarray[6]="m09d02"
   ;;
 9)
   fnarray[0]="m09d07"
   fnarray[1]="m09d12"
   fnarray[2]="m09d17"
   fnarray[3]="m09d22"
   fnarray[4]="m09d27"
   fnarray[5]="m10d02"
   ;;
 10)
   fnarray[0]="m10d07"
   fnarray[1]="m10d12"
   fnarray[2]="m10d17"
   fnarray[3]="m10d22"
   fnarray[4]="m10d27"
   fnarray[5]="m11d01"
   ;;
 11)
   fnarray[0]="m11d06"
   fnarray[1]="m11d11"
   fnarray[2]="m11d16"
   fnarray[3]="m11d21"
   fnarray[4]="m11d26"
   fnarray[5]="m12d01"
   ;;
 12)
   fnarray[0]="m12d06"
   fnarray[1]="m12d11"
   fnarray[2]="m12d16"
   fnarray[3]="m12d21"
   fnarray[4]="m12d26"
   fnarray[5]="m12d31"
   ;;
 *)
   echo "Undefined month: $1"
   exit
   ;;
esac
echo ${fnarray[*]}

mmddstr=(`FileNameMon.sh $month`) # will return an array with the month-day strings.
To get the array size, rather than the length of an array element, either ${#mmddstr[*]} or ${#mmddstr[@]} works well. One should notice that ${#mmddstr} shows something different but the max length of all the array elements.

ShowCalendar