Why Is Matlab Ignoring My If Statements? - matlab

So I have to write program that solves for these rules:
Find a six digit number in which the first digit is one more than the third, the second digit is one less than the fourth, the fifth digit is one less than the third, and the sixth digit is one more than the fourth. The sum of the second and third digits equals the first. The sum of all digits is thirty.
I am only allowed to use nested for and if statements and this is what I came up with:
for I = inf
for n4 = (1:9)
n6 = n4 + 1;
n2 = n4 -1;
for n3 = (1:9)
n1 = n3 + 1;
n5 = n3 - 1;
if (n1 - n2 == n3)
if (n1 + n2 + n3 + n4 + n5 + n6 == 30)
break
end
end
end
end
end
The issue I am having is that Matlab ignores all my if statements because at the end of the program, n1 - n2 = 0, n3 = 9, and the sum n1+n2+...+n6 = 22 not 30. This is my first project in Matlab so I hope I gave enough information for this question,
Thank you!

Code works perfectly and give right result, the only problem:
as already told break interrupts only 1 inner for loop.
If this is the whole code of your program you can use return instead of break.
Another way:
use some logical index.
For example:
flag = 0;
for I = inf
for n4 = (1:9)
n6 = n4 + 1;
n2 = n4 -1;
for n3 = (1:9)
n1 = n3 + 1;
n5 = n3 - 1;
if (n1 - n2 == n3)
if (n1 + n2 + n3 + n4 + n5 + n6 == 30)
flag = 1;
break
end
end
end
if flag==1
break
end
end
end
By the way. The answer is 918273.

Related

Is there a more efficient/less time demanding way to change this matrix size?

Let's consider my Matlab code:
T = 250;
N = 10;
B = 5000;
% starting matrix
Matrix1 = rand(T,N*3,B);
% ending matrix
Matrix2 = nan(T,B*3,N);
% the loop is very slow
for n = 1:(N*3)
for b = 1:B
if n <= 10
Matrix2(:,b,n) = Matrix1(:,n,b);
elseif n <= 20
Matrix2(:,b + B,n - N) = Matrix1(:,n,b);
else
Matrix2(:,b + B + B,n - N - N) = Matrix1(:,n,b);
end
end
end
Is there any more efficient or less time consuming way to get to the second matrix?
EDIT
The loop can written as a combination of reshape and permute operations:
Matrix2 = reshape(permute(reshape(Matrix1, T,N,3,B), [1 4 3 2]), T, B*3, N);
The primary answer can be useful for converting the loop to vectorized form:
Here is a vectorized solution:
n = 1:(N*3);
b = 1:B;
% split n based on 3 conditions
n1 = n(n <= 10);
n2 = n(n > 10 & n <= 20);
n3 = n(n > 20);
% the order of dimensions of both arrays should match
Matrix11 = permute(Matrix1, [1,3,2]);
Matrix2(:, b, n1) = Matrix11(:, b, n1);
Matrix2(:, b + B, n2 - N) = Matrix11(:, b, n2);
Matrix2(:, b + B + B, n3 - N - N) = Matrix11(:, b, n3);
The index n should be divided into three parts based on the three conditions. Also it is required to permute Matrix1 so its order of dimensions matches the order of Matrix2 to ensure that the vectorized assignment works correctly. However because the order of dimensions of Matrix1 is changed it is required to reorder the index positions when extracting subsets of Matrix11.
Equivalently permute can be applied per assignment
n = 1:(N*3);
b = 1:B;
n1 = n(n <= 10);
n2 = n(n > 10 & n <= 20);
n3 = n(n > 20);
Matrix2(:, b, n1) = permute(Matrix1(:, n1, b),[1 3 2]);
Matrix2(:, b + B, n2 - N) = permute(Matrix1(:, n2, b),[1 3 2]);
Matrix2(:, b + B + B, n3 - N - N) = permute(Matrix1(:, n3, b),[1 3 2]);

Bellman-Ford Algorithm Short predecessor Array

Having this Algorithm of Bellman-Ford with a slight change:
In line 7, instead of the inequality sign, we put >= so it becomes:
d[v] >= d[u] + w(u,v)
Now I know for a fact that it will not change the distances array and it will give me a correct answer.
But how will it affect my predecessor array on line 9? will it still give a correct answer?
If you have non positive edges it may not be a tree, for example for the following graph and starting from n1:
In the first pass:
by visiting e1: d[n2] = d[n1] + w[e1] = 1 & p[n2] = n1
by visiting e2: d[n3] = d[n2] + w[e2] = 1 & p[n3] = n2
by visiting e3: d[n4] = d[n3] + w[e3] = 1 & p[n4] = n3
by visiting e4: d[n2] = d[n4] + w[e4] = 1 & p[n2] = n4
and in all remaining passes, this will repeat. so at the end if you iterate over predecessor for example for n2 your will get: n2 <- n4 <- n3 <- n2 <- n4 <- ...
But I think if you don't have non-negative edges it works fine.

Array of symbolic vectors substitution issue - MATLAB missing ability to substitute exactly

I have an equation of symbolic vectors (in fact, usually many equations) that I'd like to substitute with a different symbolic vector. I would like MATLAB to substitute the equation with the new symbolic variables such that none of the old ones remain. I have been using the subs function, but it seems to jump at the earliest chance to use a substitution, rather than substituting exactly.
Here is an example of what I mean:
>> M = sym('m',[1,4]).'
M =
m1
m2
m3
m4
>> N = sym('n',[1,4]).'
N =
n1
n2
n3
n4
>> eqn = N(2,1) + 2*N(3,1) - 4*N(4,1)
eqn =
n2 + 2*n3 - 4*n4
>> relation = [N(1,1);N(4,1); N(3,1) - 2*N(4,1); N(2,1)]
relation =
n1
n4
n3 - 2*n4
n2
>> subs(eqn,relation,M)
ans =
m4 - 4*m2 + 2*n3
By hand, I can clearly see that eqn == m4 + 2*m3 exactly. Yet when I ask MATLAB to substitute, I am still left with +2*n3 in the equation.
I have searched around for similar issues to little avail, how can I make MatLab substitute ALL occurrences of n in my equation?
I will usually have many such equations, and I know that it is possible to substitute with m's exactly.
You can use the inverse relation, instead of using M expressed by N you can get the inverse relation - N expressed by M. This is simpler for subs because you want to replace N:
M = sym('m',[1,4]).';
N = sym('n',[1,4]).';
eqn = N(2,1) + 2*N(3,1) - 4*N(4,1);
relation = [N(1,1);N(4,1); N(3,1) - 2*N(4,1); N(2,1)];
% Get invers of relation, N => M
invRelation = struct2array(solve(M - relation, N)).';
newEqn = subs(eqn,N,invRelation);
Result:
relation =
n1
n4
n3 - 2*n4
n2
invRelation =
m1
m4
2*m2 + m3
m2
eqn =
n2 + 2*n3 - 4*n4
newEqn =
2*m3 + m4
Another simple example were subs fails
I'm not sour sure if the limitations of subs are documented, I did not find any, but here is another very simple example were subs fails:
syms x y
eun = x;
subs1 = subs(x,x,-y)
subs2 = subs(x,-x,y)
Output:
subs1 =
-y
subs2 =
x

How to vary the array elements of this matrix

Ok, i've the following FOR structure:
Ny = 246;
Nx = 190;
for n1y = 1:Ny
for n1x = 1:Nx
for n2y = 1:Ny
for n2x = 1:Nx
n1 =
n2 =
dx12 = xax(n1x) - xax(n2x);
dy12 = xay(n1y) - xay(n2y);
r12 = sqrt(dx12^2+dy12^2);
B(n1,n2) = 0.8 * exp((-1/2)*(r12/300));
end
end
end
end
Where, xax is a vector of length 190 and xay is a vector of length 246.
My doubt is, how can i determine n1 and n2 in the way that B becomes a (Nx*Ny , Nx*Ny) matrix?
Ps.: sorry for the language errors, my native language is not English.
Thanks.
Probably something like
n1 = (n1x - 1) * Ny + n1y;
n2 = (n2x - 1) * Ny + n2y;
or the same with all the x and y parts swapped.
But it seems that you are constructing a gigantic matrix B of size (246*190)^2*8 / 1e9 = 17 gigabyte! Is that really what you want?

lapack - addressing for fully packed rectangular format

I would like to use the LAPACK routines for factorisation and inversion of matrices using the fully packed rectangular format, as this requires only n(n+1)/2 elements to be stored for a symmetric nxn matrix. So far, I am setting up the matrix in 'packed' format and transform it calling routine DTPTTF. However, this requires a second array. I would like to build my matrix directly in fully packed rectangular format (to save on space) - is there an 'addressing' function which will give me the position of the i,j-th element? or could somebody point me to the relevant formula?
to partly answer my own question: inspecting the source code of DTPTTF and the example given therein, I've worked out the adress for one of the four possible constellations (the only one I need), namely uplo ='L' and trans ='N'. below is my fortran function:
! ==================================== ! returns address for RFP format
integer function ijfprf( ii, jj, n ) ! for row jj and column ii
! ==================================== ! for UPLO = 'L' and TRANSR = 'N' only!
implicit none
integer, intent(in) :: ii, jj, n
integer :: i, j, k, n1, k1
if( ii <= jj ) then
i = ii; j = jj
else
i = jj; j = ii
end if
k = n/2
if( mod(n,2) == 0 ) then ! n even
n1 = n + 1
if( i <= k ) then
ijfprf = 1 + (i - 1) * n1 + j
else
ijfprf = ( j - k - 1 ) * n1 + i - k
end if
else ! n odd
k1 = k + 1
if( i > k1 ) then
ijfprf = ( j - k1 ) * n + i - k1
else
ijfprf = ( i - 1 ) * n + j
end if
end if
return
end function ijfprf