MATLAB Answers


Calling a multivariable system of equations

Billy Worley 님이 질문을 제출함. 3 Nov 2019
최근 활동 Walter Roberson 님이 편집함. 4 Nov 2019
Let's say I have a function x = ZeroCalc(A,b) that will solve a system of equations. The user inputs a matrix of system of equations, for example: ZeroCalc([sin(x1) + x2 ; x1^2 - cos(x2)],[1;2]) and my function will solve it. The problem is:
The variables x1 and x2 are not assigned as symbolic variables. The first thing being called is the function that consists of these multiple variables, but an error occurs because x1 and x2 does not exist. I don't see how you can summon an input argument that contains undefined variables, when the first thing that can possibly be done is summon the input argument that contain them.
Any thoughts on this?

  댓글 수: 0

로그인 to comment.





답변 수: 1

John D'Errico 님의 답변 3 Nov 2019
John D'Errico 님이 편집함. 3 Nov 2019

I think you do not understand functions. And, well, I suppose this is a not uncommon problem for new users. There are at least two, (and certinaly more - when there are two, there are always more) ways you can solve this. For example, externally, create a simple function.
Afun = @(x1,x2) [sin(x1) + x2 ; x1.^2 - cos(x2)];
Here, Afun is defined as a function handle.
Afun =
function_handle with value:
As you see, I can evaluate that function at any point, and it returns a vector of values.
ans =
As well, you should see that nothing in there requires me to know the "names" of the variables I used inside the function handle, nor did x1 and x2 need to be defined in advance.
I can now pass in Afun into another function, and use it the same way.
It is even better if I write Afun to take a vector of parameters. So here, Afun2 takes what will be a vector of length 2.
Afun2 = @(X) [sin(X(1)) + X(2) ; X(1).^2 - cos(X(2))];
Afun2([2 3])
ans =
This gets you used to the idea that the function could in the future allow for more than 2 explicit variables. Perhaps your code might be able to handle a system of more than 2 equations in 2 unknowns. So tomorrow, you could use your code to solve a more complex problem...
Afun3 = @(X) [sin(X(1)) + X(2) ; X(1).^2 - cos(X(2)); X(3) - X(1) + X(2)];
ans =
b = [1;2;3];
Here, Afun3 is a function of a vector of length 3. As you see, I can evaluate it at some random point, and get a vector of length 3 out as a result. Then the solver code would be designed to solve for some point in R^3 space that would reproduce the right hand side vector b. Can I solve that problem in MATLAB? Simply enough, using fsolve, for example.
xfinal = fsolve(@(X) Afun3(X) - b,[1 1 1])
Equation solved.
fsolve completed because the vector of function values is near zero
as measured by the value of the function tolerance, and
the problem appears regular as measured by the gradient.
<stopping criteria details>
xfinal =
1.732 0.012969 4.7191
ans =
The [1 1 1] was the start point that fsolve needs to start its iterations.
See that in none of the above function handles did I ever need to predefine the variables inside the function handle. As well, I can pass those function handles into another function and use them. And I never needed to know the names of those variables in anything I do.
I said I can think of other ways to solve the problem. For example, if your function was designed to be solved symbolically, we could do it another way. But I think that what I have suggested here is what you will need.

  댓글 수: 7

표시 이전 댓글 수: 4
As I showed, you don't need to know the variable names. You can simply evaluate a function for Newton's method without needing to know the names of the variables.
But since you are using Newton's method (something you never stated when you asked your question) you need to be able to differentiate it. And, like many new users, you seem to feel you absolutely need to use symbolic forms.
So lets imagine you create a function G. Since you want to use a symbolic form, you will define the variables as symbolic, at least externally when you create G.
syms x1 x2
G = [sin(x1) + x2 ; x1^2 - cos(x2)];
Now, you can pass G into your objective function. Inside the function, you never need to care what the variables are named. They could be named Fred and Barney, for all I care.
Can you create a function from G inside your solver? Yes.
Gfun = matlabFunction(G)
Gfun =
function_handle with value:
Now we can evaluate G at any point.
ans =
As you can see, nothing needs to know the name of the variables.
But Newton's method, applied to multi-variable functions, requires a Jacobian matrix.
jacfun = matlabFunction(jacobian(G))
jacfun =
function_handle with value:
ans =
0.5403 1
2 0.14112
As you see, I can evaluate the Jacobian matrix trivially at any point. Again, do I care what the variables inside G were named? Not even remotely.
function x = SysCalc(A,X,iter,xtol,ftol)
[code goes here] %%This line of code does not know the specific system of equations.
%%It just assumes the general case where there could be x1 to xn
%% terms.
So A would be the system of equations the user wants solved, X is the initial values for all x variables, iter is the number of iterations, and x/ftol are the tolerances in x and f, that the user has to define.
So either another script file, or in the command window, the user would input: SysCalc(A,X,iter,xtol,ftol) with all the variable names replaced with actual values.
This is the format of our function. If I input SysCalc([cos(x1) + x2; sin(x2) + x1] ,[0;0],10, .001, .05), then I get an error that says x1 is not defined. As a function creator, i'm not understanding how or what I can do to this particular format that would allow me to pass any vector of size or variables through, because anytime A is ran, it's treated as a set of variables that matlab is not reading as symbological. That's why I'm saying that they need to be symbological.
It is not possible to meet your goals in MATLAB. You will need to either give up, or else change your goals.

로그인 to comment.

Translated by