function y = mfun(fun,varargin)
%MFUN   Numeric evaluation of a Maple function.
%   MFUN('fun',p1,p2,...,pk), where 'fun' is the name of a Maple 
%   function and the p's are numeric quantities corresponding to fun's 
%   parameters.  The last parameter specified may be a matrix. All other 
%   parameters must be the type specified by the Maple function.
%   MFUN numerically evaluates 'fun' with the specified parameters
%   and returns MATLAB doubles. Any singularity in 'fun' is returned 
%   as NaN.
%
%   Example:
%      x = 0:0.1:5.0;
%      y = mfun('FresnelC',x)
%
%   MFUN is not available in the Student Edition.
%
%   See also MFUNLIST, MHELP.

%   Copyright (c) 1993-1999 The Mathworks, Inc. All Rights Reserved.
%   $Revision: 1.18 $  $Date: 1999/01/04 21:55:25 $

if nargin == 0
   help mfun
   break
end

currd = digits;
d = 16;
digits(d);

a = [];
for k = 1:length(varargin)-1
   p = struct(sym(varargin{k}));
   a = [a ',' p.s];
end;
if ~isempty(a), a = [a(2:end) ',']; end;

x = varargin{length(varargin)};
if isstr(x), x = eval(x); end

[m,n] = size(x);
x = x(:).';
nans = find(isnan(x));
x(nans) = zeros(size(nans));

% format arguments for integer and real x
if all(imag(x) == 0)
   if all(x == fix(x))
      form = ['%' int2str(d) '.0f,'];
   else
      form = ['%' int2str(d+6) '.' int2str(d) 'e,'];
   end
   y = sprintf(form,x);

% format arguments for complex x
else
   form = ['%' int2str(d+6) '.' int2str(d) 'e'];
   y = sprintf([form '#' form '*i,'],[real(x); abs(imag(x))]);
   p = find(y == '#');

   % add the correct signs for imaginary parts
   s = find(imag(x) >= 0);
   if any(s)
      y(p(s)) = setstr('+'*ones(1,length(s)));
   end
   s = find(imag(x) < 0);
   if ~isempty(s) & any(s)
      y(p(s)) = setstr('-'*ones(1,length(s)));
   end
end

% additional format for the Maple MEX file
y(length(y)) = [];
y = ['[' y ']'];

[r,st] = maple(['evalf(map(s->' fun '(' a 's),' y '))']); 

emsg = 'error(''argument type not yet available.'')';
if st == 0
   r = eval(r,emsg);
   r(nans) = NaN*ones(size(nans));
   y = reshape(r,m,n);

elseif st == 1
   warning('Maple result too long.  String truncated.')
   y = r;

elseif st == 2

   % singularities in r
   if findstr(r,'singular')
      y = [',' y(2:length(y)-1) ','];  % use commas as delimiters for ALL elements
      c = find(y == ',');
      u = NaN*ones(1,m*n);

      for k = 2:length(c)
         r = y( c(k-1)+1 : c(k)-1 );
         [r,st] = maple(['evalf(' fun '(' a r '))']);
         if isempty(findstr(r,'singular')), u(k-1) = eval(r,emsg); end
      end

      u(nans) = NaN*ones(size(nans));
      y = reshape(u,m,n);

   % Overflow
   elseif findstr(r,'too large')
      y = [',' y(2:length(y)-1) ','];  % use commas as delimiters for ALL elements
      c = find(y == ',');
      u = Inf*ones(1,m*n);

      for k = 2:length(c)
         r = y( c(k-1)+1 : c(k)-1 );
         [r,st] = maple(['evalf(' fun '(' a r '))']);
         if isempty(findstr(r,'too large')), u(k-1) = eval(r,emsg); end
      end

      u(nans) = NaN*ones(size(nans));
      y = reshape(u,m,n);

   else
      error(r)
   end

% Other error messages
elseif st == 3
   error(r)
elseif st == 5
   warning('Maple(quit, done or stop) ignored.')
end

digits(currd);
