MATLAB won't give out the answer - matlab

I wrote my own function in MATLAB which will returns me a "true" if the input number is a prime number and a "false" if it isn't.
With the numbers 0, 1, and 2 it's working, but with anything above 2 it's not doing anything. (BTW, I recreated isprime, so obv I won't use that here.)
function [A] = myprime(p)
m = 2;
if p<1
disp('Number too low')
end
if p == 1
A = false;
end
if p == 2
A=true;
end
if p < 2
while m < p
A = true;
x = mod(p, m);
if x == 0
m=p;
R=false;
end
m=m+1;
end
end
end
As you can see, it gives results for 0,1 and 2, but nothing for any number above 2:

there is a problem with your code, you don't declare the state where p>2 and also I think the line that you declared
if p<2
while m<p
is not true because you set m=2 and that state won't happen.

Related

Append in Julia

I am new to Julia. A was curious how do I append values. I want b to grow every time the boolian value is True. And then to output its size.
function f(img_deformed, img)
s = size(img)[1]
for i in range(1,s,step=1)
for j in range(1,s,step=1)
b = img_deformed[i,j] == img[i,j]
end
end
return b
end
If you want b to be a vector that tracks the number of times that the equality in your for loop is satisfied, you can use push!:
function f(img_deformed, img)
s = size(img)[1]
b = Vector{Bool}() # Can also use Bool[]
for i in range(1,s,step=1)
for j in range(1,s,step=1)
if img_deformed[i,j] == img[i,j]
push!(b, true)
end
end
end
return length(b)
end
However, if all you really care about is the number of trues, it's easier (and almost certainly better) to just use b as a counter:
function f(img_deformed, img)
s = size(img)[1]
b = 0
for i in range(1,s,step=1)
for j in range(1,s,step=1)
if img_deformed[i,j] == img[i,j]
b += 1
end
end
end
return b
end
Some minor style points: s = size(img)[1] is equivalent to s = size(img, 1), and the range(1, s, step=1) is equivalent to 1:s, so your code could be written slightly more simply as
function f(img_deformed, img)
s = size(img, 1)
b = 0
r = 1:s
for i in r
for j in r
if img_deformed[i,j] == img[i,j]
b += 1
end
end
end
return b
end
However, that doesn't address a potential mistake in the original code: unless you know that img will always be a square matrix, using the same range (1:s) for both for loops is not guaranteed to be correct. To avoid this problem, you can use axes:
function f(img_deformed, img)
b = 0
for j in axes(img, 2)
for i in axes(img, 1)
if img_deformed[i,j] == img[i,j]
b += 1
end
end
end
return b
end
Notice here that I've chosen to loop over the columns first; this is a good practice in Julia, since arrays are stored in column-major order (see the explanation here from the manual).
Note also that using img to control the values that we loop over implicitly assumes that size(img) == size(img_deformed). Without knowing more about what this function is intended for, it's hard to suggest how to deal with that, but if you can assume that the two matrices should be the same size, you can add a check at the top of f(), e.g.
function f(img_deformed, img)
#assert size(img) == size(img_deformed)
# rest of code is the same
end

Plotting the Impulsefunction

so I'm new to Matlab and had to draw the Impulsefunction with y(n) is only 1 if n == 3, else 0. The following code works:
n = -5:5;
f = n; % allocate f
for i = 1 : length(n)
f(i) = dd1(n(i)-3);
end
stem(n, f);
function y = dd1(n)
y = 0;
if n == 0
y = 1;
end
end
But I feel like it's to complicated, so I tried the following:
n = -5:5
stem(n, fo)
function y = fo(n)
y = 0
if n == 3
y=1
end
end
This returns
Not enough input arguments.
Error in alternative>fo (line 5)
if n == 3
Error in alternative (line 2)
stem(n, fo)
I feel like I'm missing something trivial here.
if is no vector-wise operation but expects a single boolean (or at least a scalar that it can cast to a boolean).
But you can do this vector-wise:
lg = n == 3;
This produces a logical (MATLAB's name for boolean) array (because n is an array and not a vector), which is true where n is equal (==) to three. So you don't need a function, because you can make use of MATLAB's ability to work with vectors and arrays implicitly.
(for your code it would be f = (n-3) == 3)
A last hint: if you have a state-space system (ss-object), you can use the function step to get the step-response as a plot.

Output 1, 0.5, or 0 depending if a matrix elements are prime, 1, or neither

I am sending a matrix to my function modifikuj, where I want to replace the elements of the matrix with:
1 if element is a prime number
0 if element is a composite number
0.5 if element is 1
I dont understand why it is not working. I just started with MATLAB, and I created this function:
function B = modifikuj(A)
[n,m] = size(A);
for i = 1:n
for j = 1:m
prost=1;
if (A(i,j) == 1)
A(i,j) = 0.5;
else
for k = 2:(A(i,j))
if(mod(A(i,j),k) == 0)
prost=0;
end
end
if(prost==1)
A(i,j)=1;
else
A(i,j)=0;
end
end
end
end
With
A = [1,2;3,4];
D = modifikuj(A);
D should be:
D=[0.5, 1; 1 0];
In MATLAB you'll find you can often avoid loops, and there's plenty of built in functions to ease your path. Unless this is a coding exercise where you have to use a prescribed method, I'd do the following one-liner to get your desired result:
D = isprime( A ) + 0.5*( A == 1 );
This relies on two simple tests:
isprime( A ) % 1 if prime, 0 if not prime
A == 1 % 1 if == 1, 0 otherwise
Multiplying the 2nd test by 0.5 gives your desired condition for when the value is 1, since it will also return 0 for the isprime test.
You are not returning anything from the function. The return value is supposed to be 'B' according to your code but this is not set. Change it to A.
You are looping k until A(i,j) which is always divisible by itself, loop to A(i,j)-1
With the code below I get [0.5,1;1,0].
function A = modifikuj(A)
[n,m] = size(A);
for i = 1:n
for j = 1:m
prost=1;
if (A(i,j) == 1)
A(i,j) = 0.5;
else
for k = 2:(A(i,j)-1)
if(mod(A(i,j),k) == 0)
prost=0;
end
end
if(prost==1)
A(i,j)=1;
else
A(i,j)=0;
end
end
end
end
In addition to #EuanSmith's answer. You can also use the in built matlab function in order to determine if a number is prime or not.
The following code will give you the desired output:
A = [1,2;3,4];
A(A==1) = 0.5; %replace 1 number with 0.5
A(isprime(A)) = 1; %replace prime number with 1
A(~ismember(A,[0.5,1])) = 0; %replace composite number with 0
I've made the assumption that the matrice contains only integer.
If you only want to learn, you can also preserve the for loop with some improvement since the function mod can take more than 1 divisor as input:
function A = modifikuj(A)
[n,m] = size(A);
for i = 1:n
for j = 1:m
k = A(i,j);
if (k == 1)
A(i,j) = 0.5;
else
if all(mod(k,2:k-1)) %check each modulo at the same time.
A(i,j)=1;
else
A(i,j)=0;
end
end
end
end
And you can still improve the prime detection:
2 is the only even number to test.
number bigger than A(i,j)/2 are useless
so instead of all(mod(k,2:k-1)) you can use all(mod(k,[2,3:2:k/2]))
Note also that the function isprime is a way more efficient primality test since it use the probabilistic Miller-Rabin algorithme.

Matlab programming error

I am trying out the questions in programming assignment of Coursera course on Matlab programming as an exercise. This is for my self-study.
Question:
Write a function called classify that takes one input argument x. That
argument will have no more than two dimensions. If x is an empty
matrix, the function returns -1. If x is a scalar, it returns 0. If x
is a vector, it returns 1. Finally, if x is none of these, it returns
2. Do not use the built-in functions isempty, isscalar, or isvector.
My code snippet:
function num = classify(x)
num = -1;
if(x == 3.14159265358979)
num = 0;
elseif(size(x, 2) == 3)
num = -1;
end
end
I got the below result on Matlab.
Problem 4 (classify):
Feedback: Your function performed correctly for argument(s) []
Feedback: Your function performed correctly for argument(s) zeros(1,0)
Feedback: Your function performed correctly for argument(s) zeros(0,4)
Feedback: Your function performed correctly for argument(s) 3.14159265358979
Feedback: Your function made an error for argument(s) [1 2 3]
Am I doing something wrong for arguments [1 2 3]?
If all you want is the code, I'll provide you with the answer, but I suggest you sit down and try to understand how and why this codes solves the problem, I'm guessing you want to learn something from it. Well, here's the code:
function [num] = classify(x)
if numel(x) == 0
num = -1;
return
end
num = sum(size(x) > 1);
end
You can most easily check if x is empty or a scalar by counting the number of elements (i.e. use the numel function). Then to determine if it is a vector or a higher dimensional matrix you need to check if the number of dimensions is less than 3 (this is because ndims returns 2 for both 1D and 2D matrices) and also verify that at least one of the first two dimensions has a size of 1:
function num = classify(x)
n = numel(x);
if n < 2
num = n-1;
else
if ndims(x) < 3 && any(size(x) == 1)
num = 1;
else
num = 2;
end
end
end
You should aim to write a generic function, your function would not work for example for any scalar input than pi.
Use the size function to determine the dimensions of the input, for example:
>> size([])
ans = 0 0
>> size(5)
ans = 1 1
>> size([5 6 7])
ans = 1 3
>> size([5;6;7])
ans = 3 1
Based on this, your function could looke like this:
function [num] = classify(x)
s = size(x);
if s == [0 0]
num = -1;
elseif s == [1 1]
num = 0;
elseif sort(s) == [1 3]
num = 1;
else
num = 2;
end
end
Yes, you tring to compare an array with a float.
It allows to do that (programaticalyl wrong) thing for [] because the array is empty
And for zeros, because the array is empty again: in the first case 0 columns, and in the second 0 rows
function i=classify(x)
[m, n]=size(x);
if n==1 && m==1
i=0;
elseif (m==0 && n==0)|| (m>=1 && n==0) || (m==0 && n>=1)
i=-1;
elseif (n>=1 && m==1) || (n==1 && m>=1)
i=1;
else i=2;
end
function y=classify(x)
[a b]=size(x);
%check for empty matrix
% Do not forget that an empty matrix can be size a x 0 or 0x a, where a can be
% arbitrary number
if (a>0)&&(b==0)||(a==0)&&(b>0)||(a==0)&&(b==0)
y=(-1);
%check for scalar
elseif (a==1)&&(b==1)
y=0;
%check for vector
elseif (a>=1)&&(b==1)||(a==1)&&(b>=1)
y=1;
%other case
else
y=2;
end

Counting Number of Specific Outputs of a Function

If I have a matrix and I want to apply a function to each row of the matrix. This function has three possible outputs, either x = 0, x = 1, or x > 0. There's a couple things I'm running into trouble with...
1) The cases that output x = 1 or x > 0 are different and I'm not sure how to differentiate between the two when writing my script.
2) My function isn't counting correctly? I think this might be a problem with how I have my loop set up?
This is what I've come up with. Logically, I feel like this should work (except for the hiccup w/ the first problem I've stated)
[m n] = size(matrix);
a = 0; b = 0; c = 0;
for i = 1 : m
x(i) = function(matrix(m,:));
if x > 0
a = a + 1;
end
if x == 0
b = b + 1;
end
if x == 1
c = c + 1;
end
end
First you probably have an error in line 4. It probably should be i instead of m.
x(i) = function(matrix(i,:));
You can calculate a, b and c out of the loop:
a = sum(x>0);
b = sum(x==0);
c = sum(x==1);
If you want to distinguish x==1 and x>0 then may be with sum(xor(x==1,x>0)).
Also you may have problem with precision error when comparing double values with 0 and 1.