Algorithm for finding primitive roots from number theory - numbers

i would like to implement program for finding primitive number, for given prime number, for this one, i wrote following three program
function primitive_roots=primitive_root(p)
if ~isprime(p)
error(' p must be prime number ');
end
primitive_roots=[];
n=phi(p);
k=p-1;
for ii=2:n
if power_mod(ii,k,p)==1
primitive_roots=[primitive_roots,ii];
end
end
end
there is also power_mod function
function modresult=power_mod(a,b,c)
% this program will calculate a^b mod c
i=0;
result=1;
while i<b
result=mod(result*a,c);
i=i+1;
end
modresult=result;
end
and euler totient function
function phin=phi(n)
% this function will calculates how many coprime number exist for given n, coprime number must be
%less then n
if isprime(n) % if number is prime
phin=(n-1);
end
factors=unique(factor(n));% will printt unique prime divisors of given n
k=1; % counter
for ii=1:length(factors)
k=k*(1-1/factors(ii));
end
phin=k*n;
end
but first programs give me incorrect result, for instance
>> primitive_roots=primitive_root(19)
primitive_roots =
Columns 1 through 14
2 3 4 5 6 7 8 9 10 11 12 13 14 15
Columns 15 through 17
16 17 18
>>
while wolfram alhpa gives me different result
https://www.wolframalpha.com/widgets/view.jsp?id=ef51422db7db201ebc03c8800f41ba99
please help me

i have solved this program, for this one i introduced additional function which will calculate all possible powers and then i am checking for smallest ones
function all_powers=powers_list(a,p)
all_powers=[];
for ii=1:p-1
if power_mod(a,ii,p)==1 % finding all powers
all_powers=[all_powers,ii];
end
end
end
function primitive_roots=primitive_root(p)
if ~isprime(p)
error(' p must be prime number ');
end
primitive_roots=[];
n=phi(p);
k=p-1;
for ii=2:p-1
if power_mod(ii,k,p)==1
all_powers=powers_list(ii,p);
if (min(all_powers)==(p-1))
primitive_roots=[primitive_roots,ii];
end
end
end
>> primitive_roots=primitive_root(5)
primitive_roots =
2 3
>> primitive_roots=primitive_root(7)
primitive_roots =
3 5
>> primitive_roots=primitive_root(19)
primitive_roots =
2 3 10 13 14 15
>> primitive_roots=primitive_root(23)
primitive_roots =
5 7 10 11 14 15 17 19 20 21
>>

Related

Vectorising a Matlab code to pick specific indices of a matrix

I have a matrix A in Matlab of dimension Nx(N-1), e.g.
N=5;
A=[1 2 3 4;
5 6 7 8;
9 10 11 12;
13 14 15 16;
17 18 19 20];
I want to rearrange the elements of A in a certain way. Specifically I want to create a matrix B of dimension (N-1)xN such that:
for i=1,...,N,
B(:,i) collects
1) the first i-1 elements of the i-1th column of A and
2) the last N-i elements of the ith column of A.
Notice that for i=1 the i-1th column of A does not exist and therefore 1) is skipped; similarly, for i=N theith column of A does not exist and therefore 2) is skipped.
In the example above
B=[5 1 2 3 4
9 10 6 7 8
13 14 15 11 12
17 18 19 20 16];
This code does what I want. I am asking your help to vectorise it in an efficient way.
B=zeros(N-1,N);
for i=1:N
if i>1 && i<N
step1=A(1:i-1,i-1);
step2=A(i+1:N,i);
B(:,i)=[step1;step2];
elseif i==1
B(:,i)=A(i+1:N,i);
elseif i==N
B(:,i)=A(1:i-1,i-1);
end
end
Extract the lower and upper triangular matrices of A. Then reassemble them with a "diagonal shift":
u = triu(A);
l = tril(A,-1);
B = padarray(u(1:end-1,:),[0 1],'pre') + padarray(l(2:end,:),[0 1],'post');
Another valid approach using logical indexing combined with tril and triu:
B = zeros(size(A'));
B(tril(true(size(B)))) = A(tril(true(size(A)), -1));
B(triu(true(size(B)), 1)) = A(triu(true(size(A))));
Result:
>> B
B =
5 1 2 3 4
9 10 6 7 8
13 14 15 11 12
17 18 19 20 16

What is meant by variable = (matrix,scalar) in Octave?

a=magic(5)
k=a,3
When I print k, it simply shows a.
m=size(a,3)
n=size(a,6)
when I print m and n, they print different values.
Anyone please explain what this function is?
On Octave 4.2.1
k=a,3
assigns the matrix a to the variable k, then, as a second instruction, prints on the CommandWindow the value 3.
The , (comma) is used in order to have two instruction on the same row.
An alterntive could be replacing the , with the ; which has the effect of suppressing the output on the CommandWindow of the assignment k=a
With respect to
m=size(a,3)
n=size(a,6)
the second parameter n the call to size specifies the dimension of the matrix (the first parameter) for which you want to know the size.
a is a two "dimensional" matrix of size (5 x 5) while the instruction size(a,3) looks for the size of the third dimension of a.
In a similar way, size(a,6) looks for the size of the a's sixth dimension. In these case, the a is considered as (5 x 5 x 1) and (5 x 5 x 1 x 1 x 1 x 1)
The return value, for is 1
This is the output in the CommandWondow:
>> a=magic(5)
a =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
>> k=a,3
k =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
ans = 3
>> m=size(a,3)
m = 1
>> n=size(a,6)
n = 1
In matlab / octave, there are three ways to terminate an expression (e.g. 1+2):
With a semicolon ;
With a comma ,
With a newline (i.e. pressing enter)
The first one (i.e. the semicolon) when used, evaluates the expression, but suppresses its output. The other two (i.e. the comma and the newline), both evaluate the statement and also display its result.
Why have both a comma and a newline? Because, with a comma, you can evaluate multiple expressions on the same line (and have all of them display their results).
Note: Given the fact that most people write their expressions in separate lines, the comma tends not to be used very much, so it is less known.
Examples:
octave:1> 1+2, 3+4
ans = 3
ans = 7
octave:2> 1+2; 3+4;
octave:3> 1+2; 3+4
ans = 7
octave:4> 1+2, 3+4;
ans = 3
octave:5> for i = 1:3; i; end % output in each iteration is suppressed
octave:6> for i = 1:3; i, end % whereas with a comma, output is not suppressed
i = 1
i = 2
i = 3
Therefore your statements:
a = magic(5)
k = a, 3
are essentially equivalent to
a = magic(5) % newline used: display value of a after assignment
k = a, % comma used, assign value of a to k, then display k
3 % newline used: displays the value '3' after pressing enter
Furthermore the size function doesn't do what you think it does. size(a,3) returns the size of array a in the 3rd dimension.

How do I save the values from every iteration of a for-loop?

I have a for-loop, but every iteration overwrites the variable and I have only the final data left.
How can I save the other values from every iteration of the for-loop?
Here is the code I tried:
p = [1:1:20]';
for x = 0.1:0.1:1
q = x.*p
end
Here is the result I got:
q =
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
You can make q a two-dimensional matrix or a cell.
Two-dimensional matrix:
q=zeros(numel(p),10); %better to pre-allocate if you know the dimensions beforehand.
count=0;
for x=.1:.1:1
count=count+1;
q(:,count)=x.*p;
end
Cell:
q=cell(10); %better to pre-allocate if you know the dimensions beforehand.
count=0;
for x=.1:.1:1
count=count+1;
q{count}=x.*p;
end
Here is an alternative solution use bsxfun() It multiplies each x index with p' in just one line
p = [1:1:20]';
x = 0.1:0.1:1;
q = bsxfun(#times,x,p)

Finding middle point for consecutive number

Let say I have
A=[1 3 4 5 6 7 9 12 15 16 17 18 20 23 24 25 26];
My interest is how to find the middle value between consecutive numbers using Matlab.
For example, first group of consecutive numbers is
B=[3 4 5 6 7];
so the answer should be is 5. The 2nd group of consecutive numbers (i.e. [15 16 17 18]) should give 16 etc...
At the end, my final answer is
[5 16 24]
Here is a vectorized approach:
d = [diff(A) == 1, 0];
subs = cumsum([diff(d) == 1, 0]).*(d | [0, diff(d) == -1]) + 1
temp = accumarray(subs', A', [], #median)
final = floor(temp(2:end))
Here is some sample code which does what you are looking for. I'll let you play with the different outputs to see what they do exactly, although I wrote some comments to follow:
clear
clc
A=[1 3 4 5 6 7 9 12 15 16 17 18 20 23 24 25 26]
a=diff(A); %// Check the diff array to identify occurences different than 1.
b=find([a inf]>1);
NumElements=diff([0 b]); %//Number of elements in the sequence
LengthConsec = NumElements((NumElements~=1)) %// Get sequences with >1 values
EndConsec = b(NumElements~=1) %// Check end values to deduce starting values
StartConsec = EndConsec-LengthConsec+1;
%// Initialize a cell array containing the sequences (can have ifferent
%lengths, i.e. an array is not recommended) and an array containing the
%median values.
ConsecCell = cell(1,numel(LengthConsec));
MedianValue = zeros(1,numel(LengthConsec));
for k = 1:numel(LengthConsec)
ConsecCell{1,k} = A(StartConsec(k):1:EndConsec(k));
MedianValue(k) = floor(median(ConsecCell{1,k}));
end
%//Display the result
MedianValue
Giving the following:
MedianValue =
5 16 24
diff + strfind based approach -
loc_consec_nums = diff(A)==1 %// locations of consecutive (cons.) numbers
starts = strfind([0 loc_consec_nums],[0 1]) %// start indices of cons. numbers
ends = strfind([loc_consec_nums 0],[1 0]) %// end indices of cons. numbers
out = A(ceil(sum([starts ; ends],1)./2))%// median of each group of starts and ends
%// and finally index into A with them for the desired output

index of first greater than during two array comparison

I have two arrays threshold and values.
threshold=[10 22 97]
values=[99 23 77 11 8 10]
I want to output idx such that threshold(idx-1)<values(i)<=threshold(idx). That is for the above example output will be
output=[4 3 3 2 1 1]
The naive code that can produce above output will be
output=ones(1,length(values))*(length(values)+1);
for i=1:length(values)
for j=1:length(threshold)
if(values(i)>threshold(j))
output(i)=j;
end
end
end
Is there a simple way of doing it. I want to avoid loops.
You can use histc command, with a slight adjustment of threshold array
>> threshold=[-inf 10 22 97 inf];
>> values=[99 23 77 11 8 10];
>> [~, output] = histc( values, threshold+.1 )
output =
4 3 3 2 1 1
The modification of threshold is due to "less-than"/"less-than-equal" type of comparison for bin boundary decisions.
No loops often means you'll gain speed by increasing peak memory. Try this:
threshold = [10 22 97];
values = [99 23 77 11 8 10];
%// Do ALL comparisons
A = sum(bsxfun(#gt, values.', threshold));
%// Find the indices and the ones before
R = max(1, [A; A-1]);
%// The array you want
R(:).'
If you run out of memory, just use the loop, but then with a find replacing the inner loop.
Loops aren't all that bad, you know (if you have MATLAB > R2008). In theory, the solution above shouldn't even be faster than a loop with find, but oh well...profiling is key :)