Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
fminsearch error

Subject: fminsearch error

From: M.E.L.

Date: 12 May, 2010 20:03:21

Message: 1 of 9

I've written the following code to a least squares fit of a function. I want to find the values of k1 and k2 for which the the function is minimized.

% set ifit to 0 and don't continue on to the fit until
% the user sets it to 1
ifit=0;
while ifit==0
disp(' Enter an initial guess for the function ')
kplot=input('parameters [k1,k2] in vector form [...]- ')

% plot the data and the initial function guess
Fplot=funcfit(kplot,rplot);
figure, plot(r1,F2(:,y),'b-',rplot,Fplot,'g-')
figure, plot(r1,F2(:,y),'b-',rplot(125:325),.5*Fplot(125:325)-.38,'g-')
ifit=input(' Enter 0 to guess again, 1 to try to fit with this guess - ')
end

option=optimset('TolX',1e-10);
k=fminsearch(@(k) leastsq(k,r,A),[kx,ky],option)

The while loops works fine and my plots look good. The problem arises when I try to fit using one of my guesses.

The function leastsq is defined as:
function s=leastsq(k,r,A)
s=sum((A-(k(1).*r+k(2).*r)).^2);

and both A and r are defined as 480x480 arrays of numbers.

The error I get is:

??? Subscripted assignment dimension mismatch.

Error in ==> fminsearch at 205
fv(:,1) = funfcn(x,varargin{:});

Error in ==> FFT_DataFit2 at 97
k=fminsearch(@(k) leastsq(k,r,A),[kx,ky],option)

Am I running into problems because A and r are arrays? Help!

Subject: fminsearch error

From: Matt J

Date: 12 May, 2010 20:27:21

Message: 2 of 9

"M.E.L. " <schrodingers.lyon@gmail.com> wrote in message <hsf1i9$oio$1@fred.mathworks.com>...

>
> option=optimset('TolX',1e-10);
> k=fminsearch(@(k) leastsq(k,r,A),[kx,ky],option)
>
> The while loops works fine and my plots look good. The problem arises when I try to fit using one of my guesses.
>
> The function leastsq is defined as:
> function s=leastsq(k,r,A)
> s=sum((A-(k(1).*r+k(2).*r)).^2);
==============

Some pecularities obvious from the beginning:

(1) Your objective depends on k(1) and k(2) only through its sum, i.e., the above objective simplifies to

s=sum( (A - sum(k).*r).^2 )

This means you have a continuum of solutions, making the problem highly ill-conditioned.


(2) Your objective function above does not produce a scalar if A and r are 480x480.
Because sum() adds up individual columns by default, the result of the above sum will be a 1x480 vector.


(3) To address both (1) and (2), it's possible that you want instead the objective function

function s=leastsq(ksum,r,A)
 s=sum( (A(:) - ksum*r(:) )^2)

This however has the closed form solution

ksum=A(:)\r(:)

In general, it is strange that you would try to solve a low dimensional unconstrained quadratic minimization using an iterative method like fminsearch when these problems have analytical solutions.

====================
>
> The error I get is:
>
> ??? Subscripted assignment dimension mismatch.
>
> Error in ==> fminsearch at 205
> fv(:,1) = funfcn(x,varargin{:});
==========

The error is in funfcn which you've told us nothing about. Regardless, the problem is that it is returning an array whose size is not the same as size(fv(:,1)).

Subject: fminsearch error

From: Matt J

Date: 12 May, 2010 20:34:20

Message: 3 of 9

"Matt J " <mattjacREMOVE@THISieee.spam> wrote in message <hsf2v9$r42$1@fred.mathworks.com>...

> function s=leastsq(ksum,r,A)
> s=sum( (A(:) - ksum*r(:) )^2)
>
> This however has the closed form solution
>
> ksum=A(:)\r(:)
============

 Make that ksum=r(:)\A(:)

Subject: fminsearch error

From: M.E.L.

Date: 12 May, 2010 22:55:22

Message: 4 of 9

"Matt J " <mattjacREMOVE@THISieee.spam> wrote in message <hsf2v9$r42$1@fred.mathworks.com>...
> "M.E.L. " <schrodingers.lyon@gmail.com> wrote in message <hsf1i9$oio$1@fred.mathworks.com>...
>
> >
> > option=optimset('TolX',1e-10);
> > k=fminsearch(@(k) leastsq(k,r,A),[kx,ky],option)
> >
> > The while loops works fine and my plots look good. The problem arises when I try to fit using one of my guesses.
> >
> > The function leastsq is defined as:
> > function s=leastsq(k,r,A)
> > s=sum((A-(k(1).*r+k(2).*r)).^2);
> ==============
>
> Some pecularities obvious from the beginning:
>
> (1) Your objective depends on k(1) and k(2) only through its sum, i.e., the above objective simplifies to
>
> s=sum( (A - sum(k).*r).^2 )
>
> This means you have a continuum of solutions, making the problem highly ill-conditioned.

======================

Sloppy error, that should be rx and ry. So it's actually:

s=sum((A-((k(:,1).*rx)+(k(:,2).*ry)+(Y.*k(:,3)))).^2);

I've also included an additional term, which is a phase offset. I need to minimize k1, k2, and k3.

=======================
>
> (2) Your objective function above does not produce a scalar if A and r are 480x480.
> Because sum() adds up individual columns by default, the result of the above sum will be a 1x480 vector.

 
> (3) To address both (1) and (2), it's possible that you want instead the objective function
>
> function s=leastsq(ksum,r,A)
> s=sum( (A(:) - ksum*r(:) )^2)
>
> This however has the closed form solution
>
> ksum=A(:)\r(:)
>
> In general, it is strange that you would try to solve a low dimensional unconstrained quadratic minimization using an iterative method like fminsearch when these problems have analytical solutions.
>
 ====================
> >
> > The error I get is:
> >
> > ??? Subscripted assignment dimension mismatch.
> >
> > Error in ==> fminsearch at 205
> > fv(:,1) = funfcn(x,varargin{:});

> ==========
>
> The error is in funfcn which you've told us nothing about. Regardless, the problem is that it is returning an array whose size is not the same as size(fv(:,1)).

===============

Here's the kicker: I don't have a function called funfcn. I have no idea where it's coming from. I've just barely started using Matlab, so the whole thing is still rather mysterious to me. I'm sure my code must look ridiculous, but I very much appreciate your help!

Subject: fminsearch error

From: Matt J

Date: 13 May, 2010 02:19:07

Message: 5 of 9

"M.E.L. " <schrodingers.lyon@gmail.com> wrote in message <hsfbkq$ksb$1@fred.mathworks.com>...
 
> Sloppy error, that should be rx and ry. So it's actually:
>
> s=sum((A-((k(:,1).*rx)+(k(:,2).*ry)+(Y.*k(:,3)))).^2);
>
> I've also included an additional term, which is a phase offset. I need to minimize k1, k2, and k3.
=================

The only way this expression won't give an error is if k(:,i) are scalars and
rx, ry, rz are 480x480 . It follows that k is a vector and
you can just index this as k(i) instead of k(:,i)

In any case, my remarks from before still apply. There is no way s will work out to be a scalar if A is 480x480

Also, if this is a quadratic minimization, there is still no reason you should be using fminsearch. The minimum of any quadratic function of k1, k2, k3 has a closed-form solution obtainable much more reliably/efficiently from the backslash operator '\'.



>
> Here's the kicker: I don't have a function called funfcn. I have no idea where it's coming from. I've just barely started using Matlab, so the whole thing is still rather mysterious to me. I'm sure my code must look ridiculous, but I very much appreciate your help!
========================

It's probably called internally by fminsearch and the error is probably because, as mentioned above, your leastsq() objective function does not return a scalar.

The problem will be moot once you stop using fminsearch, as I've recommended.

Subject: fminsearch error

From: M.E.L.

Date: 13 May, 2010 20:43:19

Message: 6 of 9

Wow, you're right ... about everything! This backslash operator will work a LOT better. So let me see if I understand this. I've got some function, Y, that I'm trying to minimize

Y=A - [ (k1)rx + (k2)ry ]

where A, rx, and ry are 480x480 matrices, and k1 and k2 are the parameters I am trying to solve for. I say that Y=0, so now

A = (k1)rx + (k2)ry + k3

From what I've been able to gather from the online help, I need to create a 'design matrix', X, such that

A = X*k

and therefore k = X\A .

The online help says to create a 'design matrix' X:

X = [rx ry ones(size(rx)) ]

which, if I'm understanding this correctly, is an array that essentially has a 480x480 array of 1's and rx and ry stacked next to each other. I'm not exactly sure how or why this is helpful, but I'll just go with it.

Now if we do

k = X\A

it should spit out the values for my coefficients. What I get for k is a 480x1440 that has mostly zeros, except for two rows at 480 and 482, which have values that change as you move from left to right across the array. Am I to assume that these are the coefficients that minimize the function at each point?

Thank you again for your help as I struggle through this!

Subject: fminsearch error

From: Steven Lord

Date: 13 May, 2010 21:36:36

Message: 7 of 9


"M.E.L. " <schrodingers.lyon@gmail.com> wrote in message
news:hsho97$6n5$1@fred.mathworks.com...
> Wow, you're right ... about everything! This backslash operator will work
> a LOT better. So let me see if I understand this. I've got some
> function, Y, that I'm trying to minimize
>
> Y=A - [ (k1)rx + (k2)ry ]
>
> where A, rx, and ry are 480x480 matrices, and k1 and k2 are the parameters
> I am trying to solve for. I say that Y=0, so now

In this case, that means you have a system of (480*480) equations in two
unknowns.

> A = (k1)rx + (k2)ry + k3
>
> From what I've been able to gather from the online help, I need to create
> a 'design matrix', X, such that
>
> A = X*k
>
> and therefore k = X\A .
>
> The online help says to create a 'design matrix' X:
>
> X = [rx ry ones(size(rx)) ]
>
> which, if I'm understanding this correctly, is an array that essentially
> has a 480x480 array of 1's and rx and ry stacked next to each other. I'm
> not exactly sure how or why this is helpful, but I'll just go with it.

Not exactly. You want the first row of X to contain [rx(1), ry(1), 1] so
that when you compute [rx(1), ry(1), 1]*[k1; k2; k3] (for the k1, k2, and k3
values you're going to compute) results in the value A(1). Similarly, you
want the p'th row of X to be [rx(p), ry(p), 1] so that [rx(p), ry(p),
1]*[k1; k2; k3] is A(p). Therefore, you want to turn rx and ry into column
vectors. To do that, use colon or RESHAPE. I'll show each of those
techniques in my definition of X:

X = [rx(:), reshape(ry, [], 1), ones(numel(rx), 1)]

We want the last column of X to be a ones vector with the same number of
elements as rx, so I created that using the NUMEL function.

> Now if we do
>
> k = X\A
>
> it should spit out the values for my coefficients. What I get for k is a
> 480x1440 that has mostly zeros, except for two rows at 480 and 482, which
> have values that change as you move from left to right across the array.
> Am I to assume that these are the coefficients that minimize the function
> at each point?

Now if you use the X I created above, k should be 3-by-1.

--
Steve Lord
slord@mathworks.com
comp.soft-sys.matlab (CSSM) FAQ: http://matlabwiki.mathworks.com/MATLAB_FAQ

Subject: fminsearch error

From: M.E.L.

Date: 14 May, 2010 16:21:21

Message: 8 of 9

Thank you, Steven, for clarifying that for me! That makes more sense. But using the X that you suggested, I get an error when I try to do k=X\A:

??? Error using ==> mldivide
Matrix dimensions must agree.

Error in ==> FFT_DataFit3 at 61
k=X\A

X is a 230400x3 matrix and A is 480x480. Have I done something wrong?

Thank you!

Subject: fminsearch error

From: Steven Lord

Date: 14 May, 2010 17:13:44

Message: 9 of 9


"M.E.L. " <schrodingers.lyon@gmail.com> wrote in message
news:hsjta1$ibj$1@fred.mathworks.com...
> Thank you, Steven, for clarifying that for me! That makes more sense.
> But using the X that you suggested, I get an error when I try to do k=X\A:
>
> ??? Error using ==> mldivide
> Matrix dimensions must agree.
>
> Error in ==> FFT_DataFit3 at 61
> k=X\A
> X is a 230400x3 matrix and A is 480x480. Have I done something wrong?

No, I missed a step in my explanation. Since you "columnized" your rx and
ry, you also need to do the same to A.

k = X\(A(:))

To check, X*k should be A(:) [at least in a least-square sense.] Since X is
230400-by-3 and k is 3-by-1, the result should be 230400-by-1 which is the
size of A(:).

--
Steve Lord
slord@mathworks.com
comp.soft-sys.matlab (CSSM) FAQ: http://matlabwiki.mathworks.com/MATLAB_FAQ

Tags for this Thread

No tags are associated with this thread.

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us