yusano
yusano

Reputation: 39

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:

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]; 

Upvotes: 1

Views: 105

Answers (3)

Wolfie
Wolfie

Reputation: 30101

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.

Upvotes: 2

obchardon
obchardon

Reputation: 10792

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.

Upvotes: 1

Euan Smith
Euan Smith

Reputation: 2192

  1. 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.
  2. 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

Upvotes: 1

Related Questions