From: <HIDDEN>
Newsgroups: comp.soft-sys.matlab
Subject: Re: Element-wise matrix integraton
Date: Sun, 1 Aug 2010 04:07:05 +0000 (UTC)
Organization: The MathWorks, Inc.
Lines: 76
Message-ID: <i32rt9$had$>
References: <i2tv00$lq5$>
Reply-To: <HIDDEN>
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
X-Trace: 1280635625 17741 (1 Aug 2010 04:07:05 GMT)
NNTP-Posting-Date: Sun, 1 Aug 2010 04:07:05 +0000 (UTC)
X-Newsreader: MATLAB Central Newsreader 1187260
Xref: comp.soft-sys.matlab:658039

"Bram " <> wrote in message <i2tv00$lq5$>...
> Hi there,
> I am having trouble with integrating a matrix element-wise with respect to two variables (r and z) using dblquad. 
> I used two for-loops (inside a nested function) to create a 2D-matrix called Az(m,l) and I want to integrate all elements of that matrix between the same boundaries (rmin,rmax,zmin and zmax). The best option I could think of is using dblquad together with for loops to integrate every element independently, but other suggestions are also welcome. I placed my code below. 
> _____________________________________________________________
> function [Bz, Rho, Zeta]=MagField3 (I,rmin,rmax,zmin,zmax,rhomin,rhomax,zetamin,zetamax,n)
> rho = (linspace(rhomax,rhomin,n))';     % One column of rho-values
> Rho = repmat(rho,1,n);                  % Build square matrix
> zeta = linspace(zetamin,zetamax,n);     % One row of zeta-values
> Zeta = repmat(zeta,n,1);                % Build square matrix
> mu = 4*pi*10^-7;        % Magnetic permeability     
> k = zeros(n);   %Preallocation
> K = zeros(n);
> E = zeros(n);
> Bz = zeros(n);
>     function Az = AAz(r,z)
>         for m = linspace(1,n,n)
>            for l = linspace(1,n,n)
>                Az = zeros(n);
>                k(m,l) = sqrt((4.*r.*Rho(m,l))./((r+Rho(m,l)).^2+(Zeta(m,l)-z).^2));
>                [K(m,l),E(m,l)] = ellipke(k(m,l).^2);
>                Az(m,l) = (I*mu./(2*pi*sqrt((r+Rho(m,l)).^2+(Zeta(m,l)-z).^2))).*(K(m,l)+((r.^2-Rho(m,l).^2-(Zeta(m,l)-z).^2)./((r-Rho(m,l)).^2+(Zeta(m,l)-z).^2)).*E(m,l)); 
>             end
>         end
>     end
>     for m = linspace(1,n,n)
>         for l = linspace(1,n,n)
>             Bz(m,l) = dblquad(@(r,z)AAz(m,l),rmin,rmax,zmin,zmax);
>         end
>     end
> end
> ______________________________________________________________
> However, when I run the program I receive this error message: 
> ________________________________________________________
> ??? Index exceeds matrix dimensions.
> Error in ==> quad at 85
> if ~isfinite(y(7))
> Error in ==> dblquad>innerintegral at 84
>     Q(i) = quadf(intfcn, xmin, xmax, tol, trace, y(i), varargin{:});
> Error in ==> quad at 77
> y = f(x, varargin{:});
> Error in ==> dblquad at 60
> Q = quadf(@innerintegral, ymin, ymax, tol, trace, intfcn, ...
> Error in ==> MagField3 at 30
>             Bz(m,l) = dblquad(@(r,z)AAz(m,l),rmin,rmax,zmin,zmax);
> ________________________________________________________
> I am new to Matlab, so it is possible that I am making a very basic mistake. Can anyone help me with this?
> Thanks in advance!
> Bram
- - - - - - - - - -
  Bram, I call to your attention the statement in dblquad documentation that says, "fun(x,y) [referring to the integrand] must accept a vector x and a scalar y and return a vector of values of the integrand."

  In your code you are apparently making the assumption that the r variable as called by dblquad is a scalar and therefore that the resulting value for Az(m,l) will also be a scalar for each m and l value.  As you can see from the above quotation, that is not the way dblquad works.  Your integrand function must be prepared to accept the variable r as a vector of values and return a like-sized vector of values for the corresponding Az values.  You have no way of knowing in advance how long that vector might be, and it may vary from call to call, depending as it does on the needs of dblquad in dealing with the particular integrand values you hand to it.  The integrand function you write must be able to handle this kind of variability in the calls it receives from dblquad.

  This means that for each pair of indices m and l you must allow the values for Az to be computed in accordance with the demands made upon it by dblquad independently of all other paired values of m and l.  In other words you must have an outer double loop that computes the double integral for each m and l.  Within that loop the integration must be allowed to be completed over the specified r-z range before going on to the next pair of m and l values.  Your attempt to have an Az matrix furnishing integrands for all m and l pairs simultaneously as dblquad proceeds with its integration in a parallel fashion will not work.

Roger Stafford