Jump to content

  • Log In with Google      Sign In   
  • Create Account


[matlab] vector-valued functions...


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
8 replies to this topic

#1 binsansballs   Members   -  Reputation: 164

Like
0Likes
Like

Posted 11 October 2012 - 10:04 AM

Hi all,

I need solving nonlinear least-squares for my prototype app.
I'm referring to the lsqnonlin function:

http://www.mathworks.../lsqnonlin.html

Currently, I use the following code:
k = 1 : num
opt_r = @(x) orig_r{k}*x(1) - other_r{k}*x(k);

x = ones(1,num);
[r_exp, resnorm] = lsqnonlin(opt_r, x);

in other words, I need considering all the arrays belonging to my orig_r and other_r cell arrays.

I receive the following error:
Error using *
Too many input arguments.

What would the correct statement be?

Edited by binsansballs, 11 October 2012 - 10:05 AM.


Sponsor:

#2 apatriarca   Crossbones+   -  Reputation: 1616

Like
0Likes
Like

Posted 11 October 2012 - 02:12 PM

I haven't completely understood what you are trying to achieve. What about
[source lang="plain"]opt_r = @(x) orig_r{1:num} * x(1) - other_r{1:num} .* x(1:num);[/source]
To define vector valued functions you should usually either directly define a new vector with the square braces notation or use vector operations on vectors/matrices.

#3 binsansballs   Members   -  Reputation: 164

Like
0Likes
Like

Posted 12 October 2012 - 01:27 AM

I haven't completely understood what you are trying to achieve. What about
[source lang="plain"]opt_r = @(x) orig_r{1:num} * x(1) - other_r{1:num} .* x(1:num);[/source]
To define vector valued functions you should usually either directly define a new vector with the square braces notation or use vector operations on vectors/matrices.


The problem still remains (since it is in .* x(1:num)).

Say num = 3.
x would be a vector of size 3, and I'd like to have:

opt_r = @(x) orig_r{2}.^x(1) - other_r{2}.*x(2) + orig_r{3}.^x(1) - other_r{3}.^x(3)

#4 apatriarca   Crossbones+   -  Reputation: 1616

Like
0Likes
Like

Posted 12 October 2012 - 07:14 AM

Can you write your equation in a more mathematical notations, i.e. using series or Einstein notation or Matrix notation or.. I'm not sure what are you trying to achieve with that code. For example, why you are not considering orig_r{1} and other_r{1}? Is there any reason or you simply forgot their terms? What's the generalization to other dimensions?

#5 Emergent   Members   -  Reputation: 971

Like
0Likes
Like

Posted 12 October 2012 - 08:07 AM

What are the dimensions of orig_r? I.e., how many matrices does this cell array contain?

And what are the dimensions of its contents? I.e., what are the dimensions of orig_r{1}, and are the dimensions of orig_r{2}, orig_r{3}, etc, all the same as this?

Likewise for other_r: What are that cell array's dimensions, and what are the dimensions of the matrices that are its elements?

---

Some tips for debugging:

For now, stop using inline ("@") notation for your function. Just write a function using the standard "function" syntax that does what you want, and break the computation within it into multiple lines. Then, forget about "lsqnonlin" for now, and just try to call your function and get it to return a number. With your function split up, you will be able to set breakpoints and see what is happening. Once you know that your function works, then try calling lsqnonlin on it.

If you want to use inline function syntax, slowly move more of the computations in your function into a single line, testing at each stage. This will help you to isolate your mistake. When you do have it represented as a single line, then move that line into an inline ("@") function, and test that it works. Finally, try calling lsqnonlin on it.

Edited by Emergent, 12 October 2012 - 08:23 AM.


#6 binsansballs   Members   -  Reputation: 164

Like
0Likes
Like

Posted 12 October 2012 - 10:24 AM

One moment. I think I'm really misunderstanding something about lsqnonlin...

I've got problems even with this simple code:

opt = {3};
for i = 1 : 3
opt{i} = @(x) x^i;
end
[r resnorm] = lsqnonlin(opt,10);

the error is

FUN must be a function or an inline object;
or, FUN may be a cell array that contains these type of objects.

but class(opt) returns me a cell...

#7 Emergent   Members   -  Reputation: 971

Like
1Likes
Like

Posted 12 October 2012 - 11:34 AM

Oh! I think I understand why you're doing what you're doing. You've been getting the error message,

??? Error using ==> lsqfcnchk at 117
FUN must be a function or an inline object;
or, FUN may be a cell array that contains these type of objects.


so you've been thinking FUN can be a cell array. Then you type "help lsqnonlin," and you read

X = LSQNONLIN(FUN,X0) starts at the matrix X0 and finds a minimum X to
the sum of squares of the functions in FUN.


and that phrase "the functions in FUN" leads you to believe that there are multiple functions.

All this is extremely misleading. FUN is one function. It returns a vector. Why the MATLAB documentation confuses the issue, I do not know.

Here's a correct version of what I think you were attempting with your last code:
% answer.m
function answer()
	[x, resnorm] = lsqnonlin(@residuals, 10);
  
	fprintf('x = %g\nresnorm = %g\n', x, resnorm);
end
function r = residuals(x)
	for i=1:3
		r(i) = x^i;
	end
end

Note that the answer is trivial. We're looking for the number "x" that minimizes (x^1)^2 + (x^2)^2 + (x^3)^3, and that number is of course zero. Note also that "residuals" can be written more efficiently than above as,
function r = residuals(x)
	r = x.^[1:3];
end
and that, if you really want, you can do everything with the one-liner,
[x, resnorm] = lsqnonlin(@(x)(x.^[1:3]), 10);

Finally, I think you may also be a bit confused about cell arrays. The syntax, "opt = {3};" does not declare a cell array of size 3x1 or 1x3. It creates a cell array of size 1x1, containing the value 3. For an example of what the curly brackets do in this context, consider the statement "opt = {[1;2], eye(2), 1};" this makes a 1x3 cell array containing a 2x1 vector, a 2x2 matrix, and a scalar.

I hope that helps.

Edited by Emergent, 12 October 2012 - 11:38 AM.


#8 binsansballs   Members   -  Reputation: 164

Like
0Likes
Like

Posted 12 October 2012 - 02:29 PM

Thank you, this was exactly what I was misunderstanding!
Unfortunately, in my actual code, I can not use the first solution you suggest (the introduction of a second function would be
problematic). And for the second approach... I tried something similar but it gave me some problems since I had to iterate on
cell arrays, not on simpe arrays:

If x is a cell array, I can not use the syntax x{1:3}...

Anyway, thank you again. On Monday I'll test the function again and give you a feedback!

#9 Emergent   Members   -  Reputation: 971

Like
0Likes
Like

Posted 12 October 2012 - 03:41 PM

Unfortunately, in my actual code, I can not use the first solution you suggest (the introduction of a second function would be
problematic).


It may not be necessary, but in case it's helpful, do remember that you can both nest functions, and define multiple functions in the same file.

And for the second approach... I tried something similar but it gave me some problems since I had to iterate on
cell arrays, not on simpe arrays:

If x is a cell array, I can not use the syntax x{1:3}...


If all the elements of your cell array have the same dimension, "cell2mat" could be an option.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS