Unable to find explicit solution on vector equation with solve

Hello !
I'm trying to solve static mechanics equations, hence implying vectors.
I tried with a simple case but Matlab is unable to find an explicit solution, though it should be solvable. It seems to me as if there is an error in the code preventing Matlab to properly spot the unknowns (which are vector components).
Here's a minimal code example, with a couple of tries with solve :
syms g mS fS real positive
syms vR_S_1 vR_S_2 vR_S_3 real
vP_S = [0; 0; -mS * g];
vR_S = [vR_S_1; vR_S_2; vR_S_3];
S1 = solve([vP_S + vR_S == zeros(3, 1); vR_S(2)^2 == vR_S(3)^2 * fS^2 - vR_S(1)^2]', [vR_S(3), vR_S(1)])
S2 = solve([vP_S + vR_S == zeros(3, 1); vR_S_2^2 == vR_S_3^2 * fS^2 - vR_S_1^2]', [vR_S_3, vR_S_1])
S3 = solve(subs([vP_S + vR_S == zeros(3, 1); vR_S_2^2 == vR_S_3^2 * fS^2 - vR_S_1^2])', [vR_S_3, vR_S_1])
Any clue about what's going on ?
Many thanks in advance !

Answers (2)

S1 = solve([vP_S + vR_S == zeros(3, 1); vR_S(2)^2 == vR_S(3)^2 * fS^2 - vR_S(1)^2]', [vR_S(3), vR_S(1)])
You are trying to solve 4 equations for two variables. Most of the time that is going to fail.

1 Comment

By the way, the ' operator is the complex conjugate operator, not simply the transpose operator which is .' . When you use it the way you are using it, you introduce extraneous solutions.
If you solve vP_S + vR_S == zeros(3, 1) for vR_S then several components come out as zero

Sign in to comment.

Umar
Umar about 12 hours ago
Edited: Walter Roberson about 9 hours ago
Hi @Yanncha,
I took a close look at your code and identified everything that's going wrong — there are actually a few layered issues, some are MATLAB-specific quirks and one may be a deeper conceptual problem with the constraint equation itself.
Issue 1 Passing indexed vector elements as unknowns to solve() (S1)
In your first attempt, you pass vR_S(3) and vR_S(1) as the unknowns argument to solve(). Even though these resolve to the correct symbolic variables, MATLAB's solve() prefers to receive named scalar syms directly — the kind you declared with syms. Passing indexed vector elements can confuse the solver's internal variable detection. Your S2 attempt correctly switches to the named scalars vR_S_3 and vR_S_1, which is the right approach.
Issue 2 The conjugate transpose operator (') on an equation array
All three of your attempts apply the ' operator to the equation array. In MATLAB, ' is the Hermitian (conjugate) transpose, not the plain transpose. For symbolic equations it usually doesn't cause a visible error, but it is bad practice and can behave unexpectedly depending on MATLAB version. If you need to reshape the array, use .' (plain transpose) instead, or better yet just remove the transpose entirely — solve() handles both row and column vectors of equations without issue.
Issue 3 Leaving vR_S_2 undeclared as either an unknown or a known value (most likely cause of failure)
This is the main reason MATLAB is silently failing. You have 4 equations and ask solve() to find only 2 unknowns (vR_S_1 and vR_S_3). But vR_S_2 appears in the equations and is not declared as a known parameter — it is still a free symbolic variable. MATLAB's solver sees 3 free unknowns but is only told to solve for 2, and rather than internally eliminating vR_S_2, it tends to give up and return an empty result. The fix is to either solve for all three vR_S components at once, or manually substitute the value of vR_S_2 first before calling solve() on the remaining equation.
Issue 4 S3's bare subs() call does nothing
In your third attempt, you write subs([...equations...]). Calling subs() with only one argument and no substitution pairs is a no-op — it returns the input unchanged. So S3 is identical in behavior to S2 and is not actually testing anything different. This is worth knowing so you don't spend time treating S3 as a separate diagnostic.
Issue 5 Possible physical inconsistency in the constraint (important)
After fixing all the MATLAB issues, if you substitute the force balance solution
(vR_S_1 = 0, vR_S_2 = 0, vR_S_3 = mS*g) into the constraint equation, it
reduces to:
0 = (mS * g)^2 * fS^2
Since mS, g, and fS are all declared as real positive, this expression can never equal zero. That means the constraint as written is physically inconsistent with the force balance — they cannot be simultaneously satisfied for any nonzero mass or friction coefficient. MATLAB is not wrong to return no solution; there may genuinely be no solution. I'd recommend double-checking whether the constraint equation correctly models your physical scenario (for example, whether it should be an inequality instead of an equality, or whether the signs are correct).
Recommended approach
Rather than fighting solve() with all four equations at once, break it into steps:
Step 1 — The force balance gives you explicit values directly:
vR_S_1 = 0, vR_S_2 = 0, vR_S_3 = mS * g
Step 2 — Substitute these into the constraint separately and check whether the constraint is satisfied, or what condition on your parameters it implies.
This avoids all the solver ambiguity and also makes the physics much clearer at each step.
Hope this helps get you unstuck.

6 Comments

They did
syms vR_S_1 vR_S_2 vR_S_3 real
vR_S = [vR_S_1; vR_S_2; vR_S_3];
This results in vR_S(1) being vR_S_1 and vR_S(2) being vR_S_2 and vR_S(3) being vR_S_3 .
If you compare
solve(EQNS, [vR_S(3), vR_S(1)])
to
solve(EQNS, [vR_S_3, vR_S_1])
you will find that they go through the same symbol resolution and what will get passed in each case is (for example) [#object('sym', '__ans_4321'), #object('sym', '__ans_176')]
There is absolutely no difference (other than minor efficiency) between passing in [vR_S(3), vR_S(1)] and passing in [vR_S_3, vR_S_1] .
There would be a difference if the call had instead been
solve(EQNS, 'vR_S_3', 'vR_S_1')
but that difference would not be important.
You're absolutely right Walter, thank you for the correction. I was wrong on Issue 1 — since vR_S is constructed directly from named syms, vR_S(1) simply retrieves the same underlying symbolic object as vR_S_1, so there is no difference between the two forms when passed to solve(). The MathWorks documentation confirms solve() accepts any symbolic vector or list of variables without distinction. I should not have listed that as a contributing factor — the real issues remain the over-constrained system, the free vR_S_2 variable, and the potential physical inconsistency in the constraint.
Thank you for your detailed answers.
@Walter Roberson, I didn't know it could harm to have more equations than free variables. I can probably try to reduce the system but I was expecting Matlab would do it for me. First I was going to solve my problem by hand : largely ok for this first case but there are a bunch of them and latter ones involve 5+ unknown vectors... So I got lazy and turned to Matlab ;) (or tried to).
Ok for insights on transpose operator, I removed it and kept the vertical equations vector.
Yes I got confused about R_S_2, first I was manually substituing it before solve (but it wasn't working either) then I included it in the system.
You're right also about the physical inconsistency. I was too quick in building my minimal example, as there are normally other forces that come into action and generate the friction in x and y.
Here below is an updated code :
syms g mS fS F7 a real positive % gravity, mass, friction coeff., spring force value
syms vR_S_1 vR_S_2 vR_S_3 real % Support reaction
vP_S = [0; 0; -mS * g]; % Weight
vR_S = [vR_S_1; vR_S_2; vR_S_3]; % Unknown support reaction
vF7 = [-F7 * sind(a); F7 * cosd(a); 0]; % Spring force at angle a
S1 = solve([vP_S + vR_S + vF7 == zeros(3, 1); vR_S_2^2 == vR_S_3^2 * fS^2 - vR_S_1^2], [vR_S])
S1 = struct with fields:
vR_S_1: [0×1 sym] vR_S_2: [0×1 sym] vR_S_3: [0×1 sym]
vR_S_2 = sqrt(vR_S_3^2 * fS^2 - vR_S_1^2); % Friction
S2 = solve([vP_S + vR_S + vF7 == zeros(3, 1)], [vR_S_1, vR_S_3])
S2 = struct with fields:
vR_S_1: [0×1 sym] vR_S_3: [0×1 sym]
Now it doesn't complain but returns empty solutions.
Ok, I may have something as S1 gives a non-empty result with ReturnConditions=true (I need to check the doc to understand what this means).
S1 = solve([vP_S + vR_S + vF7 == zeros(3, 1); vR_S_2^2 == vR_S_3^2 * fS^2 - vR_S_1^2], [vR_S], ReturnConditions=true)
I also need to re-check my problem on the physical side because in fact what I want to check here is that the spring pushes harder than the friction force, that is norm(vF7) >= norm(vR_S(1:2)) (with norm vR_S(1:2) = vR_S_3 * fS).
So maybe I'd better express the problem in some other way ?
vP_S + vR_S + vF7 == zeros(3, 1)
leads to
vR_S_1 = F7 * sin(a)
vR_S_2 = -F7 * cos(a)
vR_S_3 = mS * g
and if you want
vR_S_2^2 == vR_S_3^2 * fS^2 - vR_S_1^2
to be true, you get
F7^2 * cos^2(a) = ms^2 * g^2 * fS^2 - F7^2 * sin^2(a)
or
F7^2 = ms^2 * g^2 * fS^2
or (since all variables are positive)
F7 = ms * g * fS
as necessary condition.
Thanks @Torsten,
that makes sense with the value returned by matlab :
S1 =
struct with fields:
vR_S_1: F7*sin((pi*a)/180)
vR_S_2: -F7*cos((pi*a)/180)
vR_S_3: g*mS
parameters: [1×0 sym]
conditions: F7^2*cos((pi*a)/180)^2 + F7^2*sin((pi*a)/180)^2 == fS^2*g^2*mS^2
At least now that I get something I can check my inputs and problem conditions and not be confused due to syntax or code error.

Sign in to comment.

Categories

Products

Release

R2025b

Asked:

about 19 hours ago

Commented:

26 minutes ago

Community Treasure Hunt

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

Start Hunting!