http://www.mathworks.com/matlabcentral/newsreader/view_thread/299706
MATLAB Central Newsreader  Is it possible to convert this for loop into a matrix?
Feed for thread: Is it possible to convert this for loop into a matrix?
enus
©19942015 by MathWorks, Inc.
webmaster@mathworks.com
MATLAB Central Newsreader
http://blogs.law.harvard.edu/tech/rss
60
MathWorks
http://www.mathworks.com/images/membrane_icon.gif

Mon, 27 Dec 2010 21:18:04 +0000
Is it possible to convert this for loop into a matrix?
http://www.mathworks.com/matlabcentral/newsreader/view_thread/299706#807757
Haoyang Liu
I have the following for loop:<br>
<br>
N=5000;<br>
a=rand(N,1); %in the actual program, this is not rand, but rand would do for now<br>
b=rand(N,1);<br>
c=zeros(N);<br>
for i = 1:N<br>
for j = 1:N<br>
if a(i)+b(j) >= threshold1<br>
d=f1(a(i),b(j));<br>
elseif a(i)+b(j) <= threshold2<br>
d=f2(a(i),b(j));<br>
end<br>
c(i,j)=f(a(i),b(j))/d;<br>
end<br>
end<br>
<br>
This takes a very very long time to run. I'd like to be able to speed it up via using matrix operation or other means. I should note that the inline functions in the above code are nonlinear functions of x and y. Essentially I need to populate the matrix with a function whose input depends on the position of matrix in reference to another vector.<br>
<br>
Any help is greatly appreciated.

Mon, 27 Dec 2010 21:37:31 +0000
Re: Is it possible to convert this for loop into a matrix?
http://www.mathworks.com/matlabcentral/newsreader/view_thread/299706#807760
Walter Roberson
On 27/12/10 3:18 PM, Haoyang Liu wrote:<br>
> I have the following for loop:<br>
><br>
> N=5000;<br>
> a=rand(N,1); %in the actual program, this is not rand, but rand would do<br>
> for now<br>
> b=rand(N,1);<br>
> c=zeros(N);<br>
> for i = 1:N<br>
> for j = 1:N<br>
> if a(i)+b(j) >= threshold1<br>
> d=f1(a(i),b(j));<br>
> elseif a(i)+b(j) <= threshold2<br>
> d=f2(a(i),b(j));<br>
> end<br>
> c(i,j)=f(a(i),b(j))/d;<br>
> end<br>
> end<br>
><br>
> This takes a very very long time to run. I'd like to be able to speed it<br>
> up via using matrix operation or other means. I should note that the<br>
> inline functions in the above code are nonlinear functions of x and y.<br>
> Essentially I need to populate the matrix with a function whose input<br>
> depends on the position of matrix in reference to another vector.<br>
><br>
> Any help is greatly appreciated.<br>
<br>
a_b = bsxfun(@plus, a, b.');<br>
f1pos = a_b >= threshold1;<br>
f2pos = ~f1pos & a_b <= threshold2<br>
fab = bsxfun(@f, a, b.');<br>
f1ab = bsxfun(@f1, a, b.');<br>
f2ab = bsxfun(@f2, a, b');<br>
fab(f1pos) = fab(f1pos) ./ f1ab(f1pos);<br>
fab(f2pos) = fab(f2pos) ./ f2ab(f2pos);<br>
fab(~(f1pos  f2pos)) = NaN;<br>
<br>
The NaN corresponds to the fact that you have not defined d for the case <br>
where the sum does not fall within either threshold.<br>
<br>
Probably the performance could be improved  if f or f1 or f2 can be <br>
vectorized, or if there is no third undefined possibility.

Mon, 27 Dec 2010 21:58:05 +0000
Re: Is it possible to convert this for loop into a matrix?
http://www.mathworks.com/matlabcentral/newsreader/view_thread/299706#807762
Haoyang Liu
My mistake. There is only one threshold. I'm not sure why I had threshold1 and threshold2, they are the same.<br>
<br>
Do you have any pointers as to how I can vectorize f,f1,and f2?<br>
<br>
f = constant*(x+y)*(1/x+1/y)<br>
f1 = exp(V_max(x,y))<br>
and V_max is the local maximum of a nonlinear algebraic function of x and y?<br>
<br>
Thanks for your quick response.<br>
<br>
Walter Roberson <roberson@hushmail.com> wrote in message <wG7So.18696$My1.7287@newsfe16.iad>...<br>
> On 27/12/10 3:18 PM, Haoyang Liu wrote:<br>
> > I have the following for loop:<br>
> ><br>
> > N=5000;<br>
> > a=rand(N,1); %in the actual program, this is not rand, but rand would do<br>
> > for now<br>
> > b=rand(N,1);<br>
> > c=zeros(N);<br>
> > for i = 1:N<br>
> > for j = 1:N<br>
> > if a(i)+b(j) >= threshold1<br>
> > d=f1(a(i),b(j));<br>
> > elseif a(i)+b(j) <= threshold2<br>
> > d=f2(a(i),b(j));<br>
> > end<br>
> > c(i,j)=f(a(i),b(j))/d;<br>
> > end<br>
> > end<br>
> ><br>
> > This takes a very very long time to run. I'd like to be able to speed it<br>
> > up via using matrix operation or other means. I should note that the<br>
> > inline functions in the above code are nonlinear functions of x and y.<br>
> > Essentially I need to populate the matrix with a function whose input<br>
> > depends on the position of matrix in reference to another vector.<br>
> ><br>
> > Any help is greatly appreciated.<br>
> <br>
> a_b = bsxfun(@plus, a, b.');<br>
> f1pos = a_b >= threshold1;<br>
> f2pos = ~f1pos & a_b <= threshold2<br>
> fab = bsxfun(@f, a, b.');<br>
> f1ab = bsxfun(@f1, a, b.');<br>
> f2ab = bsxfun(@f2, a, b');<br>
> fab(f1pos) = fab(f1pos) ./ f1ab(f1pos);<br>
> fab(f2pos) = fab(f2pos) ./ f2ab(f2pos);<br>
> fab(~(f1pos  f2pos)) = NaN;<br>
> <br>
> The NaN corresponds to the fact that you have not defined d for the case <br>
> where the sum does not fall within either threshold.<br>
> <br>
> Probably the performance could be improved  if f or f1 or f2 can be <br>
> vectorized, or if there is no third undefined possibility.

Mon, 27 Dec 2010 22:21:05 +0000
Re: Is it possible to convert this for loop into a matrix?
http://www.mathworks.com/matlabcentral/newsreader/view_thread/299706#807769
Matt Fig
"Haoyang Liu" wrote in message <ifb25d$ihh$1@fred.mathworks.com>...<br>
> My mistake. There is only one threshold. I'm not sure why I had threshold1 and threshold2, they are the same.<br>
> <br>
> Do you have any pointers as to how I can vectorize f,f1,and f2?<br>
<br>
<br>
Well that would depend on what is in f, f1 and f2 of course. If there is only one threshold, then you don't need an ELSEIF, you just need an ELSE.

Mon, 27 Dec 2010 22:54:39 +0000
Re: Is it possible to convert this for loop into a matrix?
http://www.mathworks.com/matlabcentral/newsreader/view_thread/299706#807773
Walter Roberson
On 27/12/10 3:58 PM, Haoyang Liu wrote:<br>
<br>
> Do you have any pointers as to how I can vectorize f,f1,and f2?<br>
><br>
> f = constant*(x+y)*(1/x+1/y)<br>
> f1 = exp(V_max(x,y))<br>
> and V_max is the local maximum of a nonlinear algebraic function of x<br>
> and y?<br>
<br>
First pass, assuming column vectors<br>
<br>
f = @(x,y) constant .* bsxfun(@(x1,y1) (x1+y1)./(1./x1 + 1./y1), x, y.');<br>
<br>
<br>
Second pass, assuming column vectors, might be slower:<br>
<br>
function res = f(x,y)<br>
flipped = false;<br>
if size(x,1) < size(y,1)<br>
t = y;<br>
y = x;<br>
x = t;<br>
flipped = true;<br>
end<br>
numx = size(x,1);<br>
numy = size(y,1);<br>
res = zeros(numx, numy);<br>
xrecip = 1./x;<br>
for K = 1 : numy<br>
res(:,K) = (x + y(K)) * (xrecip + 1./y(K));<br>
end<br>
res = constant .* res;<br>
if flipped; res = res.'; end<br>
end<br>
<br>
<br>
This second pass should use far fewer arithmetic operation calls and far <br>
fewer function calls, and may be able to use BLAS to run parts in <br>
parallel since your vectors are sufficiently long. On the other hand, it <br>
does use more matlab code and matlab code that is _theoretically_ more <br>
efficient can turn out to be much slower than builtin functions.<br>
<br>
You can remove the bit about flipping if x and y will always be the same <br>
size, or if x is always longer than y. The purpose of the flipping is to <br>
have the vectorized part of the loop operate on the longest vector. This <br>
kind of flipping is only suitable when the operations are symmetric in <br>
the variables, as is the case here. (Also, if the vector sizes are not <br>
so different, the time and memory taken to do the transpose might not be <br>
worthwhile, so you if you keep the flipping, you might want to use a <br>
fudgefactor to hold off flipping until it would gain more than the <br>
transpose loses.)

Mon, 27 Dec 2010 23:08:27 +0000
Re: Is it possible to convert this for loop into a matrix?
http://www.mathworks.com/matlabcentral/newsreader/view_thread/299706#807776
Walter Roberson
On 27/12/10 3:58 PM, Haoyang Liu wrote:<br>
<br>
> Do you have any pointers as to how I can vectorize f,f1,and f2?<br>
><br>
> f = constant*(x+y)*(1/x+1/y)<br>
> f1 = exp(V_max(x,y))<br>
> and V_max is the local maximum of a nonlinear algebraic function of x<br>
> and y?<br>
<br>
We need more information about what you mean by "the local maximum" of a <br>
function. Do you mean that V_max has a formula in 2D that might have <br>
several maxima, that the formula should be searched for the "closest" <br>
maxima to (x,y), and the value of the formula at that closest maxima <br>
should be returned? If so, then what if there are multiple maxima at the <br>
same distance? Is the search only to be along one of the axis or in 2D <br>
or along some particular vector ? Is it okay if the local maxima so <br>
found is "wimpy" compared to another local maxima that is slightly <br>
further away? Or should the partial derivatives along x and y be <br>
calculated and the maxima chosen be the largest of the maxima in the <br>
four directions (+x, x, +y, y)? Or .... ??<br>
<br>
If this general idea of searching for a maxima is what you want to do, <br>
then is it correct that different (x,y) might lead to the same maxima <br>
point because those points are all on the "hillside" of that particular <br>
maxima ? Or is the function so nonlinear as for that to be implausible? <br>
If it is not implausible, then are the hillsides sufficiently large as <br>
for it to make sense that once a local maxima is found, to look around <br>
it to the boundaries of its influence, and to "fill in" the table for <br>
all the (x,y) that are on that hillside, making it unnecessary to do the <br>
search for those points ?

Mon, 27 Dec 2010 23:27:04 +0000
Re: Is it possible to convert this for loop into a matrix?
http://www.mathworks.com/matlabcentral/newsreader/view_thread/299706#807783
Haoyang Liu
Thanks for your help.<br>
<br>
Actually, for a given x and y, V (as a function of another variable, say z), has only one maximum. But the position (w.r.t. z) and value of the maximum is different depending on the x,y pair. <br>
<br>
Walter Roberson <roberson@hushmail.com> wrote in message <M%8So.22950$DO.13893@newsfe09.iad>...<br>
> On 27/12/10 3:58 PM, Haoyang Liu wrote:<br>
> <br>
> > Do you have any pointers as to how I can vectorize f,f1,and f2?<br>
> ><br>
> > f = constant*(x+y)*(1/x+1/y)<br>
> > f1 = exp(V_max(x,y))<br>
> > and V_max is the local maximum of a nonlinear algebraic function of x<br>
> > and y?<br>
> <br>
> We need more information about what you mean by "the local maximum" of a <br>
> function. Do you mean that V_max has a formula in 2D that might have <br>
> several maxima, that the formula should be searched for the "closest" <br>
> maxima to (x,y), and the value of the formula at that closest maxima <br>
> should be returned? If so, then what if there are multiple maxima at the <br>
> same distance? Is the search only to be along one of the axis or in 2D <br>
> or along some particular vector ? Is it okay if the local maxima so <br>
> found is "wimpy" compared to another local maxima that is slightly <br>
> further away? Or should the partial derivatives along x and y be <br>
> calculated and the maxima chosen be the largest of the maxima in the <br>
> four directions (+x, x, +y, y)? Or .... ??<br>
> <br>
> If this general idea of searching for a maxima is what you want to do, <br>
> then is it correct that different (x,y) might lead to the same maxima <br>
> point because those points are all on the "hillside" of that particular <br>
> maxima ? Or is the function so nonlinear as for that to be implausible? <br>
> If it is not implausible, then are the hillsides sufficiently large as <br>
> for it to make sense that once a local maxima is found, to look around <br>
> it to the boundaries of its influence, and to "fill in" the table for <br>
> all the (x,y) that are on that hillside, making it unnecessary to do the <br>
> search for those points ?

Mon, 27 Dec 2010 23:54:14 +0000
Re: Is it possible to convert this for loop into a matrix?
http://www.mathworks.com/matlabcentral/newsreader/view_thread/299706#807790
Walter Roberson
On 27/12/10 5:27 PM, Haoyang Liu wrote:<br>
<br>
> Actually, for a given x and y, V (as a function of another variable, say<br>
> z), has only one maximum.<br>
<br>
Another definition would say that it has a maximum in every direction <br>
(if only at the outer bounds) as long as it is not flat or undefined in <br>
those directions. By indicating that it has only one maximum, you are <br>
implicitly asking for a global maximum, which is contrary to the earlier <br>
indication that you were looking for local maxima.<br>
<br>
> But the position (w.r.t. z) and value of the<br>
> maximum is different depending on the x,y pair.<br>
<br>
Is the differential available? Is it analytically solvable in at least <br>
one of the variables? If it is available but not analytically solvable <br>
in either variable, then a minimizer routine would need to be used to <br>
determine the 2D zero of the differential, which would greatly reduce <br>
the possibility of vectorization.<br>
<br>
If no differential is available, again a minimizer routine would need to <br>
be used, this time to find the minimum of the negative of the function; <br>
there would be very little opportunity for vectorization in such a case.

Wed, 29 Dec 2010 00:12:05 +0000
Re: Is it possible to convert this for loop into a matrix?
http://www.mathworks.com/matlabcentral/newsreader/view_thread/299706#808077
Haoyang Liu
Sorry, I should've been more clear. The function V, when plotted against z, has at least two maximums, but only one in the range that I'm interested in.<br>
<br>
Analytical solution for the derivative is available for dV/dx, dV/dy, and dV/dz. I guess dV/dz=0 is what I want, but I'm not sure how to integrate that into the vectorization solution you provided.<br>
<br>
Thanks,<br>
<br>
Walter Roberson <roberson@hushmail.com> wrote in message <SG9So.3684$jj5.3468@newsfe03.iad>...<br>
> On 27/12/10 5:27 PM, Haoyang Liu wrote:<br>
> <br>
> > Actually, for a given x and y, V (as a function of another variable, say<br>
> > z), has only one maximum.<br>
> <br>
> Another definition would say that it has a maximum in every direction <br>
> (if only at the outer bounds) as long as it is not flat or undefined in <br>
> those directions. By indicating that it has only one maximum, you are <br>
> implicitly asking for a global maximum, which is contrary to the earlier <br>
> indication that you were looking for local maxima.<br>
> <br>
> > But the position (w.r.t. z) and value of the<br>
> > maximum is different depending on the x,y pair.<br>
> <br>
> Is the differential available? Is it analytically solvable in at least <br>
> one of the variables? If it is available but not analytically solvable <br>
> in either variable, then a minimizer routine would need to be used to <br>
> determine the 2D zero of the differential, which would greatly reduce <br>
> the possibility of vectorization.<br>
> <br>
> If no differential is available, again a minimizer routine would need to <br>
> be used, this time to find the minimum of the negative of the function; <br>
> there would be very little opportunity for vectorization in such a case.

Wed, 29 Dec 2010 10:15:05 +0000
Re: Is it possible to convert this for loop into a matrix?
http://www.mathworks.com/matlabcentral/newsreader/view_thread/299706#808191
Haoyang Liu
I tried this without success:<br>
<br>
N=150;<br>
a=rand(N,1).*1e7;<br>
f = @(x,y) bsxfun(@(x1,y1) (x1+y1)./(1./x1 + 1./y1)./phi_small(x1,y1,fminbnd(@(H) 1*phi_small(x1,y1,H),0,1e8,optimset('TolX',1e10))), x, y.');<br>
c=f(a,a);<br>
<br>
The error message was:<br>
<br>
"??? Operands to the  and && operators must be convertible to logical scalar values.<br>
<br>
Error in ==> fminbnd at 310<br>
if ( (fu <= fw)  (w == xf) )"<br>
<br>
if I only use the first part of f, (i.e. f = @(x,y) bsxfun(@(x1,y1) (x1+y1)./(1./x1 + 1./y1), x, y.');), it run without problem, and the second part (i.e. phi_small(x1,y1,fminbnd(@(H) 1*phi_small(x1,y1,H),0,1e8,optimset('TolX',1e10))) run fine standalone too.<br>
<br>
Any idea?<br>
<br>
Thanks,<br>
<br>
<br>
<br>
"Haoyang Liu" wrote in message <ifducl$du0$1@fred.mathworks.com>...<br>
> Sorry, I should've been more clear. The function V, when plotted against z, has at least two maximums, but only one in the range that I'm interested in.<br>
> <br>
> Analytical solution for the derivative is available for dV/dx, dV/dy, and dV/dz. I guess dV/dz=0 is what I want, but I'm not sure how to integrate that into the vectorization solution you provided.<br>
> <br>
> Thanks,<br>
> <br>
> Walter Roberson <roberson@hushmail.com> wrote in message <SG9So.3684$jj5.3468@newsfe03.iad>...<br>
> > On 27/12/10 5:27 PM, Haoyang Liu wrote:<br>
> > <br>
> > > Actually, for a given x and y, V (as a function of another variable, say<br>
> > > z), has only one maximum.<br>
> > <br>
> > Another definition would say that it has a maximum in every direction <br>
> > (if only at the outer bounds) as long as it is not flat or undefined in <br>
> > those directions. By indicating that it has only one maximum, you are <br>
> > implicitly asking for a global maximum, which is contrary to the earlier <br>
> > indication that you were looking for local maxima.<br>
> > <br>
> > > But the position (w.r.t. z) and value of the<br>
> > > maximum is different depending on the x,y pair.<br>
> > <br>
> > Is the differential available? Is it analytically solvable in at least <br>
> > one of the variables? If it is available but not analytically solvable <br>
> > in either variable, then a minimizer routine would need to be used to <br>
> > determine the 2D zero of the differential, which would greatly reduce <br>
> > the possibility of vectorization.<br>
> > <br>
> > If no differential is available, again a minimizer routine would need to <br>
> > be used, this time to find the minimum of the negative of the function; <br>
> > there would be very little opportunity for vectorization in such a case.

Wed, 29 Dec 2010 10:23:22 +0000
Re: Is it possible to convert this for loop into a matrix?
http://www.mathworks.com/matlabcentral/newsreader/view_thread/299706#808196
Walter Roberson
On 29/12/10 4:15 AM, Haoyang Liu wrote:<br>
> I tried this without success:<br>
><br>
> N=150;<br>
> a=rand(N,1).*1e7;<br>
> f = @(x,y) bsxfun(@(x1,y1) (x1+y1)./(1./x1 +<br>
> 1./y1)./phi_small(x1,y1,fminbnd(@(H)<br>
> 1*phi_small(x1,y1,H),0,1e8,optimset('TolX',1e10))), x, y.');<br>
> c=f(a,a);<br>
><br>
> The error message was:<br>
><br>
> "??? Operands to the  and && operators must be convertible to logical<br>
> scalar values.<br>
><br>
> Error in ==> fminbnd at 310<br>
> if ( (fu <= fw)  (w == xf) )"<br>
><br>
> if I only use the first part of f, (i.e. f = @(x,y) bsxfun(@(x1,y1)<br>
> (x1+y1)./(1./x1 + 1./y1), x, y.');), it run without problem, and the<br>
> second part (i.e. phi_small(x1,y1,fminbnd(@(H)<br>
> 1*phi_small(x1,y1,H),0,1e8,optimset('TolX',1e10))) run fine<br>
> standalone too.<br>
><br>
> Any idea?<br>
<br>
Yup. Look at the documentation for bsxfun:<br>
<br>
"If an Mfile function is specified, it must be able to accept either <br>
two column vectors of the same size, or one column vector and one <br>
scalar, and return as output a column vector of the size as the input <br>
values."<br>
<br>
fminbnd() is not able to process column vectors. You will have to wrap <br>
the call to it with arrayfun() over x1

Wed, 29 Dec 2010 20:17:20 +0000
Re: Is it possible to convert this for loop into a matrix?
http://www.mathworks.com/matlabcentral/newsreader/view_thread/299706#808352
Haoyang Liu
How should I implement this? I have tried:<br>
<br>
>> arrayfun(fminbnd(@(H) 1*phi_small(x1,y1,H),0,1e8,optimset('TolX',1e10)),x1,y1)<br>
??? Undefined function or variable 'x1'.<br>
Error in ==> @(H)1*phi_small(x1,y1,H)<br>
Error in ==> fminbnd at 212<br>
x= xf; fx = funfcn(x,varargin{:});<br>
<br>
>> arrayfun(@(x1,y1) fminbnd(@(H) 1*phi_small(x1,y1,H),0,1e8,optimset('TolX',1e10)),x1,y1)<br>
??? Undefined function or variable 'x1'.<br>
<br>
Thanks a bunch,<br>
<br>
Walter Roberson <roberson@hushmail.com> wrote in message <u_DSo.8614$111.6134@newsfe12.iad>...<br>
> On 29/12/10 4:15 AM, Haoyang Liu wrote:<br>
> > I tried this without success:<br>
> ><br>
> > N=150;<br>
> > a=rand(N,1).*1e7;<br>
> > f = @(x,y) bsxfun(@(x1,y1) (x1+y1)./(1./x1 +<br>
> > 1./y1)./phi_small(x1,y1,fminbnd(@(H)<br>
> > 1*phi_small(x1,y1,H),0,1e8,optimset('TolX',1e10))), x, y.');<br>
> > c=f(a,a);<br>
> ><br>
> > The error message was:<br>
> ><br>
> > "??? Operands to the  and && operators must be convertible to logical<br>
> > scalar values.<br>
> ><br>
> > Error in ==> fminbnd at 310<br>
> > if ( (fu <= fw)  (w == xf) )"<br>
> ><br>
> > if I only use the first part of f, (i.e. f = @(x,y) bsxfun(@(x1,y1)<br>
> > (x1+y1)./(1./x1 + 1./y1), x, y.');), it run without problem, and the<br>
> > second part (i.e. phi_small(x1,y1,fminbnd(@(H)<br>
> > 1*phi_small(x1,y1,H),0,1e8,optimset('TolX',1e10))) run fine<br>
> > standalone too.<br>
> ><br>
> > Any idea?<br>
> <br>
> Yup. Look at the documentation for bsxfun:<br>
> <br>
> "If an Mfile function is specified, it must be able to accept either <br>
> two column vectors of the same size, or one column vector and one <br>
> scalar, and return as output a column vector of the size as the input <br>
> values."<br>
> <br>
> fminbnd() is not able to process column vectors. You will have to wrap <br>
> the call to it with arrayfun() over x1

Wed, 29 Dec 2010 21:03:06 +0000
Re: Is it possible to convert this for loop into a matrix?
http://www.mathworks.com/matlabcentral/newsreader/view_thread/299706#808358
Haoyang Liu
I realized why I was getting that error, as I was running that command in the command window... my mistake.<br>
<br>
But I now have this problem:<br>
<br>
if I have this function in place of my previous f,<br>
<br>
f = @(x,y) bsxfun(@(x1,y1) (x1+y1)./(1./x1 + 1./y1)./phi_small(x1,y1,arrayfun(@(x2,y2) fminbnd(@(H) 1*phi_small(x2,y2,H),0,1e8,optimset('TolX',1e10)),x1,y1)), x, y.');<br>
<br>
I get this error:<br>
<br>
??? Error using ==> arrayfun<br>
All of the input arguments must be of the same size and shape.<br>
Previous inputs had size 150 in dimension 1. Input #3 has size 1.<br>
<br>
Error in ==> @(x1,y1)(x1+y1)./(1./x1+1./y1)./phi_small(x1,y1,arrayfun(@(x2,y2)fminbnd(@(H)1*phi_small(x2,y2,H),0,1e8,optimset('TolX',1e10)),x1,y1))<br>
<br>
Error in ==> @(x,y)bsxfun(@(x1,y1)(x1+y1)./(1./x1+1./y1)./phi_small(x1,y1,arrayfun(@(x2,y2)fminbnd(@(H)1*phi_small(x2,y2,H),0,1e8,optimset('TolX',1e10)),x1,y1)),x,y.')<br>
<br>
Error in ==> inlinefunction at 28<br>
c=f(a,a);<br>
<br>
So the phi_small isn't giving me the 150x150 matrix I expected...<br>
<br>
<br>
<br>
<br>
"Haoyang Liu" wrote in message <ifg50g$2v5$1@fred.mathworks.com>...<br>
> How should I implement this? I have tried:<br>
> <br>
> >> arrayfun(fminbnd(@(H) 1*phi_small(x1,y1,H),0,1e8,optimset('TolX',1e10)),x1,y1)<br>
> ??? Undefined function or variable 'x1'.<br>
> Error in ==> @(H)1*phi_small(x1,y1,H)<br>
> Error in ==> fminbnd at 212<br>
> x= xf; fx = funfcn(x,varargin{:});<br>
> <br>
> >> arrayfun(@(x1,y1) fminbnd(@(H) 1*phi_small(x1,y1,H),0,1e8,optimset('TolX',1e10)),x1,y1)<br>
> ??? Undefined function or variable 'x1'.<br>
> <br>
> Thanks a bunch,<br>
> <br>
> Walter Roberson <roberson@hushmail.com> wrote in message <u_DSo.8614$111.6134@newsfe12.iad>...<br>
> > On 29/12/10 4:15 AM, Haoyang Liu wrote:<br>
> > > I tried this without success:<br>
> > ><br>
> > > N=150;<br>
> > > a=rand(N,1).*1e7;<br>
> > > f = @(x,y) bsxfun(@(x1,y1) (x1+y1)./(1./x1 +<br>
> > > 1./y1)./phi_small(x1,y1,fminbnd(@(H)<br>
> > > 1*phi_small(x1,y1,H),0,1e8,optimset('TolX',1e10))), x, y.');<br>
> > > c=f(a,a);<br>
> > ><br>
> > > The error message was:<br>
> > ><br>
> > > "??? Operands to the  and && operators must be convertible to logical<br>
> > > scalar values.<br>
> > ><br>
> > > Error in ==> fminbnd at 310<br>
> > > if ( (fu <= fw)  (w == xf) )"<br>
> > ><br>
> > > if I only use the first part of f, (i.e. f = @(x,y) bsxfun(@(x1,y1)<br>
> > > (x1+y1)./(1./x1 + 1./y1), x, y.');), it run without problem, and the<br>
> > > second part (i.e. phi_small(x1,y1,fminbnd(@(H)<br>
> > > 1*phi_small(x1,y1,H),0,1e8,optimset('TolX',1e10))) run fine<br>
> > > standalone too.<br>
> > ><br>
> > > Any idea?<br>
> > <br>
> > Yup. Look at the documentation for bsxfun:<br>
> > <br>
> > "If an Mfile function is specified, it must be able to accept either <br>
> > two column vectors of the same size, or one column vector and one <br>
> > scalar, and return as output a column vector of the size as the input <br>
> > values."<br>
> > <br>
> > fminbnd() is not able to process column vectors. You will have to wrap <br>
> > the call to it with arrayfun() over x1

Wed, 29 Dec 2010 21:27:05 +0000
Re: Is it possible to convert this for loop into a matrix?
http://www.mathworks.com/matlabcentral/newsreader/view_thread/299706#808362
Haoyang Liu
I got it working by doing this:<br>
<br>
f = @(x,y) bsxfun(@(x1,y1) (x1+y1)./(1./x1 + 1./y1), x, y.');<br>
f2 = @(x,y) phi_small(x,y,arrayfun(@(x1,y1) fminbnd(@(H) 1*phi_small(x1,y1,H),0,1e8,optimset('TolX',1e10)),x,y));<br>
<br>
<br>
c1=f(a,a);<br>
c2=f2(repmat(a,1,length(a)),repmat(a',length(a),1));<br>
c3=c1./c2;<br>
<br>
However, c2 is taking a very long time to run... c1 takes 0.003158 sec, c2 takes 30.438425 sec, if N = 150.<br>
<br>
Any idea how I can speed up c2?<br>
<br>
"Haoyang Liu" wrote in message <ifg7ma$s1s$1@fred.mathworks.com>...<br>
> I realized why I was getting that error, as I was running that command in the command window... my mistake.<br>
> <br>
> But I now have this problem:<br>
> <br>
> if I have this function in place of my previous f,<br>
> <br>
> f = @(x,y) bsxfun(@(x1,y1) (x1+y1)./(1./x1 + 1./y1)./phi_small(x1,y1,arrayfun(@(x2,y2) fminbnd(@(H) 1*phi_small(x2,y2,H),0,1e8,optimset('TolX',1e10)),x1,y1)), x, y.');<br>
> <br>
> I get this error:<br>
> <br>
> ??? Error using ==> arrayfun<br>
> All of the input arguments must be of the same size and shape.<br>
> Previous inputs had size 150 in dimension 1. Input #3 has size 1.<br>
> <br>
> Error in ==> @(x1,y1)(x1+y1)./(1./x1+1./y1)./phi_small(x1,y1,arrayfun(@(x2,y2)fminbnd(@(H)1*phi_small(x2,y2,H),0,1e8,optimset('TolX',1e10)),x1,y1))<br>
> <br>
> Error in ==> @(x,y)bsxfun(@(x1,y1)(x1+y1)./(1./x1+1./y1)./phi_small(x1,y1,arrayfun(@(x2,y2)fminbnd(@(H)1*phi_small(x2,y2,H),0,1e8,optimset('TolX',1e10)),x1,y1)),x,y.')<br>
> <br>
> Error in ==> inlinefunction at 28<br>
> c=f(a,a);<br>
> <br>
> So the phi_small isn't giving me the 150x150 matrix I expected...<br>
> <br>
> <br>
> <br>
> <br>
> "Haoyang Liu" wrote in message <ifg50g$2v5$1@fred.mathworks.com>...<br>
> > How should I implement this? I have tried:<br>
> > <br>
> > >> arrayfun(fminbnd(@(H) 1*phi_small(x1,y1,H),0,1e8,optimset('TolX',1e10)),x1,y1)<br>
> > ??? Undefined function or variable 'x1'.<br>
> > Error in ==> @(H)1*phi_small(x1,y1,H)<br>
> > Error in ==> fminbnd at 212<br>
> > x= xf; fx = funfcn(x,varargin{:});<br>
> > <br>
> > >> arrayfun(@(x1,y1) fminbnd(@(H) 1*phi_small(x1,y1,H),0,1e8,optimset('TolX',1e10)),x1,y1)<br>
> > ??? Undefined function or variable 'x1'.<br>
> > <br>
> > Thanks a bunch,<br>
> > <br>
> > Walter Roberson <roberson@hushmail.com> wrote in message <u_DSo.8614$111.6134@newsfe12.iad>...<br>
> > > On 29/12/10 4:15 AM, Haoyang Liu wrote:<br>
> > > > I tried this without success:<br>
> > > ><br>
> > > > N=150;<br>
> > > > a=rand(N,1).*1e7;<br>
> > > > f = @(x,y) bsxfun(@(x1,y1) (x1+y1)./(1./x1 +<br>
> > > > 1./y1)./phi_small(x1,y1,fminbnd(@(H)<br>
> > > > 1*phi_small(x1,y1,H),0,1e8,optimset('TolX',1e10))), x, y.');<br>
> > > > c=f(a,a);<br>
> > > ><br>
> > > > The error message was:<br>
> > > ><br>
> > > > "??? Operands to the  and && operators must be convertible to logical<br>
> > > > scalar values.<br>
> > > ><br>
> > > > Error in ==> fminbnd at 310<br>
> > > > if ( (fu <= fw)  (w == xf) )"<br>
> > > ><br>
> > > > if I only use the first part of f, (i.e. f = @(x,y) bsxfun(@(x1,y1)<br>
> > > > (x1+y1)./(1./x1 + 1./y1), x, y.');), it run without problem, and the<br>
> > > > second part (i.e. phi_small(x1,y1,fminbnd(@(H)<br>
> > > > 1*phi_small(x1,y1,H),0,1e8,optimset('TolX',1e10))) run fine<br>
> > > > standalone too.<br>
> > > ><br>
> > > > Any idea?<br>
> > > <br>
> > > Yup. Look at the documentation for bsxfun:<br>
> > > <br>
> > > "If an Mfile function is specified, it must be able to accept either <br>
> > > two column vectors of the same size, or one column vector and one <br>
> > > scalar, and return as output a column vector of the size as the input <br>
> > > values."<br>
> > > <br>
> > > fminbnd() is not able to process column vectors. You will have to wrap <br>
> > > the call to it with arrayfun() over x1