What am I doing wrong with syms?

3 views (last 30 days)
Hello everybody I am trying to make a program that simulates a ray going through a 2d matrix on a set angle, and then highlight the path. When I get to the syms part, I get the "Unable to find explicit solution" error many times. What am I doing wrong there? Thanks in advance!!
clc
clear all
close all
a=randi([0,64],[6,6]); %create a 6*6 matrix with random values
first_row=1; %set entry point coords
entrypoint=3; %set entry point coords
a(first_row,entrypoint)=0; %pinpoint the entry point in the matrix
angle=45; %set an angle
y(1)=entrypoint; %we're gonna need these in the loop
x(1)=first_row; %we're gonna need these in the loop
for i=2:1:length(a) %repeat till it reaches the end of the matrix
syms x(i) y(i) %define the 2 unknown factors
x(i)=(((y(i)-y(i-1))*(sind(90-angle))/sin(angle))+x(i-1)); %based on A/sin(a)=B/sin(b)
y(i)=((x(i)-x(i-1))*tand(angle)+y(i-1));%based on A/sin(a)=B/sin(b)
t=floor(solve(x(i))); %solve for y
z=floor(solve(y(i))); %solve for x
a(t,z)=0; %highlight the "path" on matrix a
end
t %check
z %check
a %check
image(a)
  1 Comment
Walter Roberson
Walter Roberson on 19 Oct 2018
You have a typo: sin(angle) should be sind(angle)

Sign in to comment.

Accepted Answer

Walter Roberson
Walter Roberson on 19 Oct 2018

You have

 for i=2:1:length(a)  %repeat till it reaches the end of the matrix 

so you expect i to be an integer value.

But on the next line you have

syms x(i) y(i)    %define the 2 unknown factors

which is the same as

i = sym('i');
x = symfun(sym('x(i)'), i);
y = symfun(sym('y(i)'), i);

so i becomes an unresolved symbolic value and x and y become symbolic functions.

And that means that when you get to

    x(i)=(((y(i)-y(i-1))*(sind(90-angle))/sind(angle))+x(i-1));  %based on A/sin(a)=B/sin(b) 

then x becomes a symbolic function with parameter i, involving y evaluated at the unresolved symbol i and i-1, and also involving the previous symbolic function x (that has no definition) evaluated at i-1 .

Then

    y(i)=((x(i)-x(i-1))*tand(angle)+y(i-1));%based on A/sin(a)=B/sin(b)

y becomes a symbolic function with parameter i, involving the just-defined symbolic function x(i) evaluated at a couple of inputs, and involving the previous symbolic function y (that has no definition) evaluated at i-1 .

This is a mess, and it is not clear what your intentions are.

Perhaps the following will be meaningful to you:

a = randi([0,64],[6,6]); %create a 6*6 matrix with random values
first_row=1; %set entry point coords
entrypoint=3; %set entry point coords
a(first_row,entrypoint)=0;    %pinpoint the entry point in the matrix
angle=45;   %set an angle
syms x y yi
y(1)=entrypoint;  %we're gonna need these in the loop
x(1)=first_row;    %we're gonna need these in the loop
for i=2:1:length(a)  %repeat till it reaches the end of the matrix 
  x(i)=(((yi-y(i-1))*(sind(90-angle))/sind(angle))+x(i-1));  %based on A/sin(a)=B/sin(b) 
  y(i)=((x(i)-x(i-1))*tand(angle)+y(i-1));%based on A/sin(a)=B/sin(b)
  t = double(floor(solve( subs(x(i), yi, y(i)))));  %solve for y
  z = double(floor(solve(y(i))));  %solve for x
  if t > 0 && z > 0
    a(t,z)=0;     %highlight the "path" on matrix a
  else
      fprintf('At iteration #%d, solution outside matrix: (t,z) = (%d,%d)\n', i, t, z);
  end
end

Chances are that it won't be what you want...

  2 Comments
Serafeim Klimantiris
Serafeim Klimantiris on 20 Oct 2018
Edited: Serafeim Klimantiris on 20 Oct 2018
Thanks for the pointers! What I am trying to do is a ray tracing algorithm. So "first_row" and "entrypoint" define the point at which a supposed ray enters the matrix with said "angle".In order to trace it we need the coordinates of each next element in the matrix. Given the fact that we know the entry point (a(1,1)) and the angle, using some basic algebra we can find a(x2,y2) and so on. What I fail to do is make matlab solve a 2 equations/2 unknown variables system with syms. So in my code x and y should be vectors containing the numbers of columns and rows on matrix 'a' which represent the ray path. I have made some changes to your code(which correctly utilises syms) but now get the "Error in sym/subsref (line 841) R_tilde = builtin('subsref',L_tilde,Idx);" at line 13(the equation part).
clc
clear all
close all
a=randi([0,64],[6,6]); %create 6*6 matrix with random value
first_row=1; %set entry point coords
entrypoint=1; %set entry point coords
a(first_row,entrypoint)=0; %pinpoint the entry point in the matrix
angle=45; %set an angle
syms x y %define the 2 unknown factors
for i=2:1:length(a) %repeat till it reaches the end of the matrix
x(1)=entrypoint; at %we need these for the first itteration
y(1)=first_row; %we need these for the first itteration
x(i)=(((y(i)-y(i-1))*sind(90-angle))/sind(angle))+x(i-1); %based on A/sin(a)=B/sin(b)
y(i)=(((x(i)-x(i-1))*tand(angle))+y(i-1));%based on A/sin(a)=B/sin(b)
t = double(floor(solve( subs(y(i), x(i))))); %solve for y
z = double(floor(solve(x(i)))); %solve for x
if t > 0 && z > 0
a(t,z)=0; %highlight the "path" on matrix a
else
fprintf('At iteration #%d, solution outside matrix: (t,z) = (%d,%d)\n', i, t, z);
end
end
a %check the matrix
image(a)
Walter Roberson
Walter Roberson on 20 Oct 2018
There is no point assigning to x(1) and y(1) each iteration: those can go outside of the loop.
When you try to calculate x(2) you try to do so in terms of y(2) but at that point y is a scalar symbol so y(2) does not exist. That is why I introduce yi to act as the symbolic unknown.
Perhaps after assigning to y(i) there should be
ysol = solve(y(i), yi)
x(i) = subs(x(i), yi, ysol) ;
y(i) = subs(y(i), yi, ysol) ;
t = floor(double(x(i))) ;
z = floor(double(y(i))) ;

Sign in to comment.

More Answers (1)

Serafeim Klimantiris
Serafeim Klimantiris on 21 Oct 2018
First of all, I would like to thank you for helping me understand syms! I have made the program work with some more changes(basically on the math part). Right now it only works for 45 degrees and entry point a(1,1). If I change either it gives me an error. I should probably create a stopping rule
clc
clear all
close all
a = randi([0,64],[10,10]); %create a 6*6 matrix with random values
first_row=1; %set entry point coords
entrypoint=1; %set entry point coords
a(first_row,entrypoint)=64; %pinpoint the entry point in the matrix
angle=45; %set an angle
syms x y xi
y(1)=entrypoint; %we're gonna need these in the loop
x(1)=first_row; %we're gonna need these in the loop
for i=2:1:length(a) %repeat till it reaches the end of the matrix
y(i)=((xi-x(i-1))*tand(angle))+y(i-1);%based on A/sin(a)=B/sin(b)
x(i)= (xi^2 - (2*xi*x(i-1))-1+(y(i)^2)-(2*(y(i)*y(i-1)))+(y(i-1)^2)+(x(i-1)^2)== 0);
x(i)=subs(x(i), y(i), ((xi-x(i-1))*tand(angle))+y(i-1) );
xsol=round(solve(x(i),xi))
ysol=round(solve(x(i),y(i)))
x(i)=xsol(2)
y(i)=ysol(2)
fx=xsol(2)
fy=ysol(2)
if fx > 0 && fy > 0
a(fx,fy)=64; %highlight the "path" on matrix a
else
fprintf('At iteration #%d, solution outside matrix: (fx,fy) = (%d,%d)\n', i, fx, fy);
end
end
image(a)
  1 Comment
Walter Roberson
Walter Roberson on 22 Oct 2018
You should rarely be passing an expression for the second argument of subs() . Your expression
x(i)=subs(x(i), y(i), ((xi-x(i-1))*tand(angle))+y(i-1) );
is saying to look into x(i) for expressions that just happen to have the same substructure as the expression y(i) does, and change those places to be ((xi-x(i-1))*tand(angle))+y(i-1) instead. If the substructure does not appear exactly the same (perhaps because numeric coefficients were combined) then nothing would be substituted.
And in
ysol=round(solve(x(i),y(i)))
you are asking to solve the expression x(i) for the expression stored in y(i) -- what does that mean?? Especially after the subs() you did which would have replaced y(i) with something else.

Sign in to comment.

Tags

Community Treasure Hunt

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

Start Hunting!