How to set lower and upper bound for only one of the output variable in lsqnonlin?

Hi,
In the documentation of lsqnonlin, following statement is written:
x = lsqnonlin(fun,x0,lb,ub) defines a set of lower and upper bounds on the design variables in x, so that the solution is always in the range lb ≤ x ≤ ub. You can fix the solution component x(i) by specifying lb(i) = ub(i).
How can we write this in case we want to make sure that at the end of optimization, specfic solution components are zero? Problem that I am solving is explained in detail below.
In the problem that I want to optimize, I am using an initial guess to find the location of zero (discontinuity edge) in a data using square root fitting which is not a perfect fit but a rather good guess for intial value (based on the problem and literature that I have read). Now, end goal of the optimization is to find the optimum location for the discontinuity edge. However, the function also has another lsqnonlin in it to find the coefficients around the discontinuity edge which is giving me 4x2 matrix. Values for coefficients at npower = -1 would go to zero at the discountinuity edge.
Is there a way to set the above condition in lower and upper bound for second lsqnonlin function? Attaching the code just in case someone wants to run the function. Following is the line that I used to run lsqnonlin
[cracktip,resnorm] = lsqnonlin(@(X)williamsctip(X,cracklinefit,coefs,v,u,rint,rext),200,170,sqrttip(counter2))
%200 is the initial guess while square root fitting gave us 210.5226. Using this as initial returns the same
%Ideally the edge should lie between 170 to 210.5226 so I selected these as lower and upper bounds.
Cheers,
Waqas

 Accepted Answer

I can't follow all of the details of what you presented but regarding your initial question:
How can we write this in case we want to make sure that at the end of optimization, specfic solution components are zero?
I would suggest just assigning lb(i) = 0 ub(i) = 0 for each of the components that should be held at zero

6 Comments

That I understand that it is possible to hold particular components which we want to hold but my question is more about sentex in this case. Following way is not complying with legal use of "=" :
coefs = lsqnonlin(fun,previouscoefs,[previouscoefs(1,:)=0],...
[previouscoefs(1,:)=0],options); % For inner lsqnonlin function
The line of code that I mentioned and the attached functions should work atleast for troubleshooting the problem and give a clear understanding about the question. Let me know if you need any explaination about the details.
Sorry I was unable to run the code that you attached. I copied the errors and warning I got below. However, without looking at all of that, I can see
[previouscoefs(1,:)=0]
is not a legal matlab statement. You can't do another assignment within the definition of a matrix. Also it is not quite clear what you are trying to do here. I think maybe you are trying to set the lower and upper bounds to zero whereever the previous coefficients equal zero.
You probably need to break it up into some additional lines, something like
% I assume other coefficients are unbounded but if you have some bounds you could put them in
lb = -inf(size(previouscoefs));
ub = -lb;
idl = previouscoefs==0;
lb(idl) = 0;
ub(idl) = 0;
lsqnonlin(fun,previouscoefs,lb,ub,...
>> load matlab
Warning: Variable 'cracklinefit' originally saved as a cfit cannot be instantiated as an object and will be read in as a uint32.
>> [cracktip,resnorm] = lsqnonlin(@(X)williamsctip(X,cracklinefit,coefs,v,u,rint,rext),200,170,sqrttip(counter2))
Unrecognized function or variable 'coefs'.
Error in @(X)williamsctip(X,cracklinefit,coefs,v,u,rint,rext)
Error in lsqnonlin (line 206)
initVals.F = feval(funfcn{3},xCurrent,varargin{:});
Caused by:
Failure in initial objective function evaluation. LSQNONLIN cannot continue.
Sorry for that. Please follow the google drive link to access the complete .mat file
Looking forward to your answer.
Please look at the first paragraph and code at the top of my previous comment. Hopefully this answers your question.
Thanks. It atleast clears out the query of sentex that I was looking for. Just a few follow up questions:
  1. Is it possible to use lsqnonlin to simultaneously look for cracktip [1x1] and coefs [4x2]? Their sizes are mentioned in the square brackets.
  2. If a function, williamsctip, is giving me coefs of size [4x2] which is calculated based on cracktip (what I want to eventually find using lsqnonlin) then, once we use williamsctip in lsqnonlin how can we still get the values of coefs so that we can use them for the next iterations?
[cracktip resnorm] = lsqnonlin(@(X)williamsctip(X,cracklinefit,coefs,v,u,rint,rext),200,200,215,options)
The lsqnonlin function expects a function, fun, which returns an [nx1] vector. You may need to make a new function that includes some intermediate steps, to reshape the array outputs of some of your functions into vectors, and returns a vector. You can use the reshape function for this purpose. Note MATLAB stores values columnwise, so if you reshape an array [a b;c d;e f;g h] into a vector the elements will be ordered a,c,e,g,b,d f, h
Actually if you just want to turn a 2-d matrix into a vector you can just use the colon operator.
For example if you have a 4x2 matrix called A, then v = A(:) will return a vector with the elements of A ordered columnwise

Sign in to comment.

More Answers (0)

Asked:

on 4 Oct 2019

Edited:

Jon
on 4 Oct 2019

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!