PARI/GP: How to get the max prime factor of the integer? - pari-gp

I am new to pari/gp. I use factorint to find all the prime factors and it returns a matrix.
I am trying to traverse through a matrix to find the largest number inside but unable to find the length of rows and columns. Also how can i use the if to compare each element is higher or lower. My p is being generated on top.
temp = factorint(p-1);
num = 0;
for(i=1, size,
for(j=1, size,
if(num <= temp[i,j], num = temp[i,j]);
);
);
print("number is = " num);
Thanks in advance.

Please, note that factorint(p) always returns the nx2-matrix, where n is the number of the prime factors for p. First column is for the prime factors. Second column is for their multiplicities.
So all you need is to find the maximum element of the first column. It can be done as follows:
factors = factorint(p-1);
print("number is = ", vecmax(factors[, 1]));
By the way, the length of vector v is just #v in PARI/GP.

Besides matsize, you could also use #. For example,
factorint(30) gives a 3x2 matrix;
[2 1]
[3 1]
[5 1]
#factorint(30) gives the number of colums of that matrix (which is 2).
By transposing the matrix, the resulting matrix has 3 columns, which is the number of distinct prime factors of 30.
Transposing can be done as follows: append ~ to a matrix.
So we could do
#factorint(30)~
to get the number of distinct prime factors;
which prints
[2 3 5]
[1 1 1]
As those prime factors will be increasingly ordered in the first row, the last one in the first row is the largest one hence
factorint(30)[#factorint(30)~, 1] gives the largest prime factor of 30; 5
Now you could avoid factoring 30 twice by doing;
f = factorint(30); f[#f~]
to get 5 as desired.

Related

Randomly sampling from each element of a vector

Let's say I have a numeric vector X
X <- c(1,42,1,23,5,7)
I would like to create another vector Y with the same number of elements, each of which is a randomly generated whole number from a sequence in which 1 is the lower bound and the element in X is the upper bound e.g for Y[2] the number would be a randomly generated number selected from between 1 and 42 and for Y[4] the number would be randomly selected from between 1 and 23.
I have tried to use the apply function to do this
Y<-apply(C, 1, sample)
but I am having no luck and generating the error message
Error in apply(X, 1, sample) : dim(X) must have a positive length1,
sample
Is there a better way to do this?
You can't use apply for a vector, but for multidimensional objects only (e.g., matrices). You have to use sapply instead. Futhermore, you need the argument size = 1 since you want to sample one value for each entry of X.
sapply(X, sample, size = 1)
[1] 1 7 1 16 3 6

Convert a one column matrix to n x c matrix

I have a (nxc+n+c) by 1 matrix. And I want to deselect the last n+c rows and convert the rest into a nxc matrix. Below is what I've tried, but it returns a matrix with every element the same in one row. I'm not sure why is this. Could someone help me out please?
tmp=x[1:n*c,]
Membership <- matrix(tmp, nrow=n, ncol=c)
You have a vector x of length n*c + n + c, when you do the extract, you put a comma in your code.
You should do tmp=x[1:(n*c)].
Notice the importance of parenthesis, since if you do tmp=x[1:n*c], it will take the range from 1 to n, multiply it by c - giving a new range and then extract based on this new range.
For example, you want to avoid:
(1:100)[1:5*5]
[1] 5 10 15 20 25
You can also do without messing up your head with indexing:
matrix(head(x, n*c), ncol=c)

How to check if a vector contains an unordered sequence of numbers from 1 to N

I'm looking to check if a vector of data is in rank form. That is; each observations is a number between 1 and N, where N is the number of observations, but in a random, unknown order.
The simplest check I could think of was the gaussian sum, using (N * (N + 1)) / 2 and comparing that to the sum of the vector. Except in my case I have 200,000 observations and the sum of all numbers from 1 to 200,000 is greater than 2^32. Apart from getting a 64 bit computer what is the fastest method of checking that data is in rank form.
checkForRanks <- setdiff(1:N,X)
isRanked <- length(checkForRanks) > 0
if(!isRanked) stop("Please rank data")

Convert vector into a triangular matrix

I have a vector of 874! elements, which I want to turn into a triangular matrix (i.e. the top right hand corner of a square matrix).
Example Input:
1
2
3
4
5
6
7
8
9
10
Example Output:
1 2 4 7
3 5 8
6 9
10
Blanks could be filled with NAs. I'd prefer if the matrix were this way around.
I don't know which programming language do you want to use neither do I understand which order do you want your numbers to be stored in.
You should consider that having N elements, if you want to generate an square matrix its dimensions (n rows and columns) are given by:
N = (n*(n+1))/2
So a first approach (you should consider if your input vector has x^2/2 elements) in Python could be:
from math import sqrt
x = range(1,25+1) # This is your input vector
N = len(x)
#N = (n*(n+1))/2 # Number of elements being stored in a triangular matrix.
n = (-1.0+sqrt(1.0+8.0*N))/2.0 # Solve the equation given by the previous relation.
n = int(round(n)) # Making it integer...
while (n*(n+1))/2 < N: # ... losing precission so we should use the first n being able ...
if (n*(n+1))/2 < N: # ... to store your vector is used.
n += 1
res = [[0]*n for i in xrange(n)] # Here, we create a n*n matrix filled with zeros.
x = x[::-1] #Reverse the input so it can be consumed using pop (O(1) each extraction)
for j in xrange(n): # Fill the empty matrix following the triangular pattern and using...
if not x:
break
for i in xrange(j+1):
if not x:
break
res[i][j] = x.pop() # The elements from your input vector.
for row in res: # Let's print the result!
print(row)
The idea is to consume x filling the square matrix (res) with is values in the right order. This can easily done once you now your target matrix dimesions.

How to create a list from an array of z-scores in R?

I have an array of z-scores that is structured like num [1:27, 1:11, 1:467], so there are 467 entries with 27 rows and 11 columns. Is there a way that I can make a list from this array? For example a list of entries which contain a z-score over 2.0 (not just a list of z scores, a list which identifies which 1:467 entries have z > 2).
Say that your array is called z in your R session. The function you are looking for is which with the argument arr.ind set to TRUE.
m <- which(z > 2, arr.ind=TRUE)
This will give you a selection matrix, i.e. a matrix with three columns, each line corresponding to an entry with a Z-score greater than 2. To know the number of Z-scores greater than 2 you can do
nrow(m)
# Note that 'sum(z > 2)' is easier.
and to get the values
z[m]
# Note that 'z[z > 2]' is easier

Resources