From: Enrico on
I get a vertcat error message when using Matlab's fsolve routine and I think there is a bug in the parsing algorithm. The details will follow but I also want to note and issue with fsolve when passing a function that uses the "cross" function. I seem to get the same error when passing a function that takes cross products of the passed variables.

First Problem - the spacing around the "5" (last term) causes problems.
Below is a function that can solve…

F = [test(1) + test(3)*cos(cam_angle_send ) - abs(test(3))*mu2*sin(cam_angle_send );
test(2) + test(3)*sin(cam_angle_send ) + abs(test(3))*mu2*cos(cam_angle_send );
r1_x*test(3)*sin(cam_angle_send ) - r1_y*test(3)*cos(cam_angle_send ) + r1_x*abs(test(3))*mu2*cos(cam_angle_send ) - r1_y*-abs(test(3))*mu2*sin(cam_angle_send ) - 5];


also solvable…
F = [test(1) + test(3)*cos(cam_angle_send ) - abs(test(3))*mu2*sin(cam_angle_send );
test(2) + test(3)*sin(cam_angle_send ) + abs(test(3))*mu2*cos(cam_angle_send );
r1_x*test(3)*sin(cam_angle_send ) - r1_y*test(3)*cos(cam_angle_send ) + r1_x*abs(test(3))*mu2*cos(cam_angle_send ) - r1_y*-abs(test(3))*mu2*sin(cam_angle_send )-5];

also solvable…
F = [test(1) + test(3)*cos(cam_angle_send ) - abs(test(3))*mu2*sin(cam_angle_send );
test(2) + test(3)*sin(cam_angle_send ) + abs(test(3))*mu2*cos(cam_angle_send );
r1_x*test(3)*sin(cam_angle_send ) - r1_y*test(3)*cos(cam_angle_send ) + r1_x*abs(test(3))*mu2*cos(cam_angle_send ) - r1_y*-abs(test(3))*mu2*sin(cam_angle_send )- 5];


NOT solvable…

F = [test(1) + test(3)*cos(cam_angle_send ) - abs(test(3))*mu2*sin(cam_angle_send );
test(2) + test(3)*sin(cam_angle_send ) + abs(test(3))*mu2*cos(cam_angle_send );
r1_x*test(3)*sin(cam_angle_send ) - r1_y*test(3)*cos(cam_angle_send ) + r1_x*abs(test(3))*mu2*cos(cam_angle_send ) - r1_y*-abs(test(3))*mu2*sin(cam_angle_send ) -5];

Second Problem - the following function solves...
function F = Solve_Forces_Simple(test,r1,cam_angle,mu2)
F = [test(1) + test(3)*cos(cam_angle) - abs(test(3))*mu2*sin(cam_angle);
test(2) + test(3)*sin(cam_angle) + abs(test(3))*mu2*cos(cam_angle);
r1(1)*test(3)*sin(cam_angle) - r1(2)*test(3)*cos(cam_angle) + r1(1)*abs(test(3))*mu2*cos(cam_angle) - r1(2)*-abs(test(3))*mu2*sin(cam_angle) + 5];

However the following function gets me the "vertcat" error message - again they should be functionally identical....
function F = Solve_Forces_Simple(test,r1,cam_angle,mu2)
F = [test(1) + test(3)*cos(cam_angle) - abs(test(3))*mu2*sin(cam_angle);
test(2) + test(3)*sin(cam_angle) + abs(test(3))*mu2*cos(cam_angle);
cross(r1,[(test(3)*cos(cam_angle)),(test(3)*sin(cam_angle)),0])+cross(r1,[(abs(test(3))*mu2*cos(cam_angle)),(abs(test(3))*mu2*sin(cam_angle)),0])+5];
From: Walter Roberson on
Enrico wrote:
> I get a vertcat error message when using Matlab's fsolve routine and I
> think there is a bug in the parsing algorithm.

> NOT solvable…

> F = [test(1) + test(3)*cos(cam_angle_send ) -
> abs(test(3))*mu2*sin(cam_angle_send );
> test(2) + test(3)*sin(cam_angle_send ) +
> abs(test(3))*mu2*cos(cam_angle_send );
> r1_x*test(3)*sin(cam_angle_send ) - r1_y*test(3)*cos(cam_angle_send
> ) + r1_x*abs(test(3))*mu2*cos(cam_angle_send ) -
> r1_y*-abs(test(3))*mu2*sin(cam_angle_send ) -5];

This is nothing to do with fsolve() or cross(); it is a property of the
parser. You are within [] and within [] there is ambiguity as to whether A -B
indicates minus(A,B) or indicates horzcat(A,minus(0,B)). As is standard for
computer languages, - immediately followed by a literal is treated as a
negative constant rather than as a subtraction. This is considered to be no
more surprising than that foo([3,5]) is to be parsed as foo with an argument
which is the list horzcat(3,5) instead of to be parsed as foo with two
arguments, one of which is the invalid list "[3" and the other of which is the
invalid list "5]" . It is, in other words, a matter of parsing precedence, and
every language has parsing precedence, if only to say that () is a grouping
operator. (Okay, maybe Forth doesn't have an precedence ;-) )
From: Enrico on
I'm not 100% about the "normal convention" claim but this assumes the user using Matlab is WELL aware of what horzcat is and how to pass it variables; that's a significant assumption.

Either way, this smacks of a problem in documentation and the error message returned by Matlab. It would greatly facilitate troubleshooting if the error message returned by fsolve would educate the user of these nuances. I debugged through the fsolve.m file which never called a horzcat function - I'm sure other functions did - but I couldn't track it down, as one would expect from fcns that spawn other fcns.

It would be great to,
1) Update the documentation of fsolve AND functions in general
2) Update the error message returned to educate the user about this nuance if given a vertcat error message.
From: Walter Roberson on
Enrico wrote:
> I'm not 100% about the "normal convention" claim but this assumes the
> user using Matlab is WELL aware of what horzcat is and how to pass it
> variables; that's a significant assumption.
> Either way, this smacks of a problem in documentation and the error
> message returned by Matlab. It would greatly facilitate troubleshooting
> if the error message returned by fsolve would educate the user of these
> nuances. I debugged through the fsolve.m file which never called a
> horzcat function - I'm sure other functions did - but I couldn't track
> it down, as one would expect from fcns that spawn other fcns.
>
> It would be great to,
> 1) Update the documentation of fsolve AND functions in general
> 2) Update the error message returned to educate the user about this
> nuance if given a vertcat error message.

fsolve never gets called for your situation.

>> F = [.123; .456; 1.789 -1]
??? Error using ==> vertcat
CAT arguments dimensions are not consistent.

It would be inappropriate to document this under fsolve because it is not a
matter for fsolve. To document it under fsolve would be like requiring that
fsolve also document the error you get if you mis-match string delimeters.

The Getting Started documentation implies this situation. In "Matrices and
Magic Squares" it says to separate the elements of the list with spaces. What
are elements of the list? They can be numbers -- and the description of
numbers in the Expressions section of Getting Started indicates that,

"MATLAB uses conventional decimal notation, with an optional decimal point and
leading plus or minus sign, for numbers."

The notation for numbers thus takes priority over the notation for expressions
connecting numbers with operators.

Or see Constructing A Simple Matrix, under Programming Fundamentals:


Constructing a Simple Matrix

The simplest way to create a matrix in MATLAB is to use the matrix constructor
operator, []. Create a row in the matrix by entering elements (shown as E
below) within the brackets. Separate each element with a comma or space:
row = [E1, E2, ..., Em] row = [E1 E2 ... Em]

For example, to create a one row matrix of five elements, type
A = [12 62 93 -8 22];

To start a new row, terminate the current row with a semicolon:
A = [row1; row2; ...; rown]

This example constructs a 3 row, 5 column (or 3-by-5) matrix of numbers. Note
that all rows must have the same number of elements:
A = [12 62 93 -8 22; 16 2 87 43 91; -4 17 -72 95 6]
A =
12 62 93 -8 22
16 2 87 43 91
-4 17 -72 95 6



If your interpretation were to hold, then [12 62 93 -8 22] would have to
construct a row matrix of *four* elements instead of *five*, since you would
require the "93 -8" to be interpreted as minus(93,8), leading to
[12 62 85 22]. Likewise, in the 2D array example, the "93 -8" and "17 -72"
would, in your interpretation, need to be parsed as subtractions, but clearly
according to the examples they are not.

Space _is_ significant in Matlab.
From: Enrico on
I've used Matlab for over 15 yrs and the only time I've run into this issue is when using Fsolve as I'm usually solving equation sets and not manipulating matrices as my examples highlight. In this paradigm, the nuances can get get lost.

Fsolve IS called as I've debugged and stepped my way right into it.

Your choice - you can listen to a user's request or rebuff it - it makes no difference to me; I know the solution to my problem and I'm choosing to take the time to share it here in hopes that future users will find it useful. Thanks for your help.