I have an OpenCL code where i invoke clEnqueueWriteBuffer and clEnqueueNDRangeKernel inside a loop multiple time. I measure the data transfer time and the kernel execution time of each loop using GetLocalTime function. The issue I am facing is that the clEnqueueWriteBuffer and clEnqueueNDRangeKernel in the first iteration takes much longer to complete than the ones in the second iteration. Why does this happen?
I am working on a system with ARM A10 APU. My opencl loop code is :
for(j = 0; j < PARTITION_COUNT; j++){
//Writing to input buffers
GetLocalTime(&start);
clEnqueueWriteBuffer(queue[0], buf_A, CL_TRUE, 0, PARTITION_SIZE * sizeof(int), input_A + (PARTITION_SIZE * j), 0, NULL, &eventList[0]);
checkErr(cl_err, "clEnqueueWriteBuffer : buf_A");
clEnqueueWriteBuffer(queue[1], buf_B, CL_TRUE, 0, PARTITION_SIZE * sizeof(int), input_B + (PARTITION_SIZE * j), 0, NULL, &eventList[1]);
checkErr(cl_err, "clEnqueueWriteBuffer : buf_B");
clEnqueueWriteBuffer(queue[2], buf_C, CL_TRUE, 0, PARTITION_SIZE * sizeof(int), input_C + (PARTITION_SIZE * j), 0, NULL, &eventList[2]);
checkErr(cl_err, "clEnqueueWriteBuffer : buf_C");
clEnqueueWriteBuffer(queue[3], buf_D, CL_TRUE, 0, PARTITION_SIZE * sizeof(int), input_D + (PARTITION_SIZE * j), 0, NULL, &eventList[3]);
checkErr(cl_err, "clEnqueueWriteBuffer : buf_D");
clFinish(queue[0]);
clFinish(queue[1]);
clFinish(queue[2]);
clFinish(queue[3]);
//getting end time
GetLocalTime(&end);
//displaying final time
cout<<"\nTime : "<<start.wMinute<<" "<<start.wSecond<<" "<<start.wMilliseconds;
cout<<"\nTime : "<<end.wMinute<<" "<<end.wSecond<<" "<<end.wMilliseconds;
GetLocalTime(&start);
cl_err = clEnqueueNDRangeKernel(queue[4],kernel[Q6_PROGRAM_ID][FILTER1_KERNEL],1,NULL,&globalSize,&localSize,4,eventList,&eventList[4]);
checkErr(cl_err, "clEnqueueNDRangeKernel : filter1_kernel");
//clFinish(queue[4]);
//Invoking the second filter kernel
cl_err = clEnqueueNDRangeKernel(queue[5],kernel[Q6_PROGRAM_ID][FILTER2_KERNEL],1,NULL,&globalSize,&localSize,1,eventList + 4,&eventList[5]);
checkErr(cl_err, "clEnqueueNDRangeKernel : filter2_kernel");
//clFinish(queue[5]);
//Invoking the third filter kernel
cl_err = clEnqueueNDRangeKernel(queue[6],kernel[Q6_PROGRAM_ID][FILTER3_KERNEL],1,NULL,&globalSize,&localSize,1,eventList + 5,&eventList[6]);
checkErr(cl_err, "clEnqueueNDRangeKernel : filter3_kernel");
//clFinish(queue[6]);
//Invoking the aggregate kernel
cl_err = clEnqueueNDRangeKernel(queue[8],kernel[Q6_PROGRAM_ID][AGGREGATE_KERNEL],1,NULL,&globalSize,&localSize,1,eventList + 6,&eventList[7]);
checkErr(cl_err, "clEnqueueNDRangeKernel : aggregate kernel");
output_A = (int *)clEnqueueMapBuffer(queue[9],output_buf_A,CL_TRUE, CL_MAP_READ, 0, rLen * sizeof(int), 1, eventList + 7, &eventList[8], &cl_err);
checkErr(cl_err, "clEnqueueReadBuffer : output_A");
for(i = 0; i < rLen; i++){
if(output_A[i] > 0){
//cout<<"\n"<<output_A[i];
sum += output_A[i];
}
}
clFinish(queue[4]);
clFinish(queue[5]);
clFinish(queue[6]);
clFinish(queue[8]);
clFinish(queue[9]);
GetLocalTime(&end);
//displaying final time
cout<<"\nTime1 : "<<start.wMinute<<" "<<start.wSecond<<" "<<start.wMilliseconds;
cout<<"\nTime1 : "<<end.wMinute<<" "<<end.wSecond<<" "<<end.wMilliseconds;
}
GetLocalTime(&end1);
//displaying final time
cout<<"\nTime2 : "<<start1.wMinute<<" "<<start1.wSecond<<" "<<start1.wMilliseconds;
cout<<"\nTime2 : "<<end1.wMinute<<" "<<end1.wSecond<<" "<<end1.wMilliseconds;
my output is :
Time : 27 30 404
Time : 27 30 466
Time1 : 27 30 474
Time1 : 27 30 547
Time : 27 30 551
Time : 27 30 555
Time1 : 27 30 561
Time1 : 27 30 582
Time : 27 30 587
Time : 27 30 591
Time1 : 27 30 597
Time1 : 27 30 617
Time : 27 30 622
Time : 27 30 627
Time1 : 27 30 638
Time1 : 27 30 659
Time : 27 30 670
Time : 27 30 675
Time1 : 27 30 679
Time1 : 27 30 699
Time : 27 30 706
Time : 27 30 711
Time1 : 27 30 718
Time1 : 27 30 737
Time2 : 27 30 404
Time2 : 27 30 743
PROGRAM EXECUTION OVER
Related
just looking for an easy way to run trig functions in SAS without having to manually correct in each calculation. Below is what I am working with.
I am running this in SAS 9 probably, the SAS Studio Student Module but this is a general SAS question.
I have manually created a variable, 'rad' in the 'calc' data step to deal with this but it adds a step of complexity that I would like to avoid.
I am asking whether there is a system setting, alternate trig function or ... ? that would change the calculation from:
bh_x = cos(rad*bh_a)*bh_l ;
to:
bh_x = cos(bh_a)*bh_l ;
so I don't have to manually convert my angle in degrees to radians for the trig function to work.
Thanks to anyone reading this and putting any mental effort to the solution!
Tim
data spec ;
length
b2h_a 8
b2h_l 8
b2h_l_e 8
bike $ 8
name $ 16
;
input
bike $
name $
bh_a
bh_l
ht_a
spcr
st_h
st_a
st_l
hb_r
hb_a
;
datalines ;
srcn (0,0) 0 0 67 0 0 0 0 0 0
srcn c 41 658 71.5 27 40 25 120 100 13
srcn ne_27_n13 41 658 71.5 27 40 27 127 100 13
srcn ne_15_0 41 658 71.5 15 40 27 127 100 0
srcn ne_5_0 41 658 71.5 5 40 27 127 100 0
srcn ne_2_n9 41 658 71.5 2 40 27 127 100 9
srcn ne_5_10 41 658 71.5 5 40 27 127 100 -10
srcn ne_10_rf10 41 658 71.5 10 40 27 127 20 -10
srcn max 41 658 90 250 0 0 250 0 0
;
run ;
data calc ;
set spec ;
pi=constant('pi') ;
rad=pi/180 ;
bh_x = cos(rad*bh_a)*bh_l ;
bh_y = sin(rad*bh_a)*bh_l ;
sr_x = (cos(rad*ht_a)*(spcr+st_h/2))*-1 ;
sr_y = sin(rad*ht_a)*(spcr+st_h/2);
st_x = cos(rad*(90-ht_a+st_a))*st_l ;
st_y = sin(rad*(90-ht_a+st_a))*st_l ;
hb_x = cos(rad*(90-hb_a))*hb_r*-1 ;
hb_y = sin(rad*(90-hb_a))*hb_r ;
hd_x = bh_x + sr_x + st_x + hb_x ;
hd_y = bh_y + sr_y + st_y + hb_y ;
if hd_x=0 then do ;
b2h_a=0 ;
b2h_l=0 ;
end ;
else do ;
b2h_a = atan(hd_y/hd_x)/rad ;
b2h_l = hd_y/sin(b2h_a*rad) ;
end ;
b2h_l_e = b2h_l/25.4 ;
drop pi rad ;
format
b2h_a 5.
b2h_l 5.
b2h_l_e 5.
bh_a 5.
bh_l 5.
ht_a 5.
spcr 5.
st_h 5.
st_a 5.
st_l 5.
hb_r 5.
hb_a 5.
bh_x 5.
bh_y 5.
sr_x 5.
sr_y 5.
st_x 5.
st_y 5.
hb_x 5.
hb_y 5.
hd_x 5.
hd_y 5.
b2h_a 5.
b2h_l 5.
b2h_l_e 5.1
;
run ;
There are no trig functions in SAS that accept DEGREE or GRADIAN arguments. You always need to convert from your data's angular measurement system to RADIAN.
You can write a macro to perform the conversion. Example:
%macro cosD(theta);
%* theta is angle in degrees;
%* emit data step source code that performs conversion from degrees to radians;
cos(&theta*constant('PI')/180)
%mend;
In use:
data calc ;
set spec ;
bh_x = %cosD(bh_a) * bh_l ;
You could convert the angular data to radians during the step where input occurs and then not have to worry about it again.
I want to calculate number of items waiting or queued over. Let's say, I have fixed capacity of 102 item/hour and different incoming items for 9 hours.
as data table:
dt<-data.table(hour = c(1,2,3,4,5,6,7,8,9),
incoming = c(78,102,115,117,105,99,91,80,71),
capacity = rep(102,9))
I want to calculate queued items in each period.
In 1 and 2 capacity is enough and queue is 0.
In 3, 13 items are queued
In 4, 15+13 backlogged items are queued.
In 6, there were 31 backlogged items and 3 items are deducted so 28 were queued.
I have tried several options but could not figure out how to calculate.
Result should be:
Explicit looping in R won't get you far, and I don't see a vectorized solution for this, but this is trivial to solve using Rcpp:
library(Rcpp)
cppFunction("NumericVector queue(NumericVector x) {
NumericVector res(x.size());
res[0] = std::max<double>(0, x[0]);
for (int i = 1, size = x.size(); i < size; ++i) {
res[i] = std::max<double>(0, res[i-1] + x[i]);
}
return res;
}")
dt[, queued := queue(incoming - capacity)][]
# hour incoming capacity queued
#1: 1 78 102 0
#2: 2 102 102 0
#3: 3 115 102 13
#4: 4 117 102 28
#5: 5 105 102 31
#6: 6 99 102 28
#7: 7 91 102 17
#8: 8 80 102 0
#9: 9 71 102 0
I'd create a separate function to get queued number like #sebastian-c did, but with #R.S. 's logic. Like this
get_queue <- function(x){
n <- length(x)
y <- c(max(0, x[[1]]), rep(0, n - 1))
for(i in 2:n){
y[i] <- max(0, y[i - 1] + x[i])
}
y
}
And then
dt[,incoming_capacity := incoming - capacity]
dt[,queued := get_queue(incoming_capacity)]
Another alternative:
require(data.table)
dt<-data.table(hour = c(1,2,3,4,5,6,7,8,9),
incoming = c(78,102,115,117,105,99,91,80,71),
capacity = rep(102,9))
dt$incoming_capactity<- dt$incoming-dt$capacity
dt$carriedover<- 0
dt$carriedover[1]<- max(0,dt$incoming_capactity[1]) #added
for( i in 2:length(dt$carriedover)) {
dt$carriedover[i]<- max(0,dt$incoming_capactity[i] + dt$carriedover[i-1])
}
dt
So I'm pretty new to R, so if someone could help me out that would be great.
I'm using a program called NOISeq, which is an R based piece of software which detects differential gene expression between a number of factors. I've read in a table to a data frame which looks like this:
X10G48 X35Y87 X36W26 X23Y79 X2B84 X12Y30 X10B70 X10G87 X36W62
XLOC_000001 33 34 39 74 43 43 34 28 42
XLOC_000002 17 42 44 67 38 58 41 29 25
XLOC_000003 0 0 0 0 0 0 6 0 0
XLOC_000004 0 0 0 2 0 0 10 0 0
XLOC_000005 44 57 37 71 45 47 49 53 36
XLOC_000006 43 46 42 71 53 53 49 48 18
X23Y70 X2UNA X12Y47 X10R99
XLOC_000001 82 38 28 23
XLOC_000002 58 53 28 27
XLOC_000003 0 0 0 12
XLOC_000004 0 0 4 2
XLOC_000005 47 67 48 39
XLOC_000006 53 61 37 26
The table is sorted by two factors, such that 10G48, 35Y87, 36W26, 23Y79, 2B84, 12Y30, 10B70 are all condition 1, and 10G87, 36W62, 23Y70, 2UNA, 12Y47, 10R99 are all condition 2.
I've used the code:
library(NOISeq)
setwd("/home/user/edgeR")
data.frame <- read.table("nalphavbeta.txt", header=TRUE, sep='\t', row.names=1)
myfactors=data.frame(c(1,1,1,1,1,1,1,2,2,2,2,2,2))
sam<-readData(data=data.frame, factors=myfactors)
myRPKM = rpkm(assayData(sam)$exprs, k = 0, lc = 1)
head(myRPKM[, 1:4])
mynoiseqbio = noiseqbio(sam, k=0.5, norm="rpkm", factor=NULL, lc = 1, r = 20, adj = 1.5, plot = FALSE, a0per = 0.9, random.seed = 12345, filter = 2)
But it returns the error
Error in .subset(x, j) : invalid subscript type 'list'
I have a feeling it's to do with the factors argument, but I'm not sure exactly what. Any help would be much appreciated - thanks!
Problem solved
I just needed to change the line
myfactors=data.frame(c(1,1,1,1,1,1,1,2,2,2,2,2,2))
to
myfactors=data.frame(caste= c(1,1,1,1,1,1,1,2,2,2,2,2,2))
i.e. give the factor a name, then add the factor level into the function
mynoiseqbio = noiseqbio(sam, k=0.5, norm="rpkm", factor=caste, lc = 1, r = 20, adj = 1.5, plot = FALSE, a0per = 0.9, random.seed = 12345, filter = 2)
Just a matter of curiosity, is the Gray code defined for bases other than base two?
I tried to count in base 3, writing consecutive values paying attention to change only one trit at a time. I've been able to enumerate all the values up to 26 (3**3-1) and it seems to work.
000 122 200
001 121 201
002 120 202
012 110 212
011 111 211
010 112 210
020 102 220
021 101 221
022 100 222
The only issue I can see, is that all three trits change when looping back to zero. But this is only true for odd bases. When using even bases looping back to zero would only change a single digit, as in binary.
I even guess it can be extended to other bases, even decimal. This could lead to another ordering when counting in base ten ... :-)
0 1 2 3 4 5 6 7 8 9 19 18 17 16 15 14 13 12 11 10
20 21 22 23 24 25 26 27 28 29 39 38 37 36 35 34 33 32 31 30
Now the question, has anyone ever heard of it? Is there an application for it? Or it is just mathematical frenzy?
Yes. Have a look at the Gray code article at wikipedia. It has a section on n-ary Gray Code.
There are many specialized types of Gray codes other than the binary-reflected Gray code. One such type of Gray code is the n-ary Gray code, also known as a non-Boolean Gray code. As the name implies, this type of Gray code uses non-Boolean values in its encodings.
Just for completeness (as aioobe already gave the right answer), here's a C++ program that lists all the 168 2-digit gray codes for base 3 that start with 00 and marks the 96 cyclic ones. Using the algorithm from Wikipedia, you can construct longer Gray codes easily for even bases. For uneven bases, you can change the program to generate according Gray codes.
The first cyclic 2-digit gray code found with this program is this one:
00 01 02 12 10 11 21 22 20
After changing the program, the first cyclic 3-digit gray found is this:
000 001 002 012 010 011 021 020 022 122 102 100 101 111
110 112 212 202 222 220 120 121 221 201 211 210 200
Code:
#include <stdio.h>
#include <stdlib.h>
// Highest number using two trits
#define MAXN 9
int gray_code_count, cyclic_count;
bool changes_one_trit(int code1, int code2) {
int trits_changed = 0;
if ((code1 / 3) != (code2 / 3)) trits_changed++;
if ((code1 % 3) != (code2 % 3)) trits_changed++;
return (trits_changed == 1);
}
int generate_gray_code(int* code, int depth) {
bool already_used;
if (depth == MAXN) {
for (int i = 0; i < MAXN; i++) {
printf("%i%i ", code[i]/3, code[i]%3);
}
// check if cyclic
if (changes_one_trit(code[MAXN-1], 0)) {
printf("cyclic");
cyclic_count++;
}
printf("\n");
gray_code_count++;
}
// Iterate through the codes that only change one trit
for (int i = 0; i < MAXN; i++) {
// Check if it was used already
already_used = false;
for (int j = 0; j < depth; j++) {
if (code[j] == i) already_used = true;
}
if (already_used) continue;
if (changes_one_trit(code[depth-1], i)) {
code[depth] = i;
generate_gray_code(code, depth + 1);
}
}
}
int main() {
int* code = (int*)malloc(MAXN * sizeof(int));
code[0] = 0;
gray_code_count = 0;
generate_gray_code(code, 1);
printf("%i gray codes found, %i of them are cyclic\n", gray_code_count, cyclic_count);
free(code);
}
How to calculate modulus of 5^55 modulus 221 without much use of calculator?
I guess there are some simple principles in number theory in cryptography to calculate such things.
Okay, so you want to calculate a^b mod m. First we'll take a naive approach and then see how we can refine it.
First, reduce a mod m. That means, find a number a1 so that 0 <= a1 < m and a = a1 mod m. Then repeatedly in a loop multiply by a1 and reduce again mod m. Thus, in pseudocode:
a1 = a reduced mod m
p = 1
for(int i = 1; i <= b; i++) {
p *= a1
p = p reduced mod m
}
By doing this, we avoid numbers larger than m^2. This is the key. The reason we avoid numbers larger than m^2 is because at every step 0 <= p < m and 0 <= a1 < m.
As an example, let's compute 5^55 mod 221. First, 5 is already reduced mod 221.
1 * 5 = 5 mod 221
5 * 5 = 25 mod 221
25 * 5 = 125 mod 221
125 * 5 = 183 mod 221
183 * 5 = 31 mod 221
31 * 5 = 155 mod 221
155 * 5 = 112 mod 221
112 * 5 = 118 mod 221
118 * 5 = 148 mod 221
148 * 5 = 77 mod 221
77 * 5 = 164 mod 221
164 * 5 = 157 mod 221
157 * 5 = 122 mod 221
122 * 5 = 168 mod 221
168 * 5 = 177 mod 221
177 * 5 = 1 mod 221
1 * 5 = 5 mod 221
5 * 5 = 25 mod 221
25 * 5 = 125 mod 221
125 * 5 = 183 mod 221
183 * 5 = 31 mod 221
31 * 5 = 155 mod 221
155 * 5 = 112 mod 221
112 * 5 = 118 mod 221
118 * 5 = 148 mod 221
148 * 5 = 77 mod 221
77 * 5 = 164 mod 221
164 * 5 = 157 mod 221
157 * 5 = 122 mod 221
122 * 5 = 168 mod 221
168 * 5 = 177 mod 221
177 * 5 = 1 mod 221
1 * 5 = 5 mod 221
5 * 5 = 25 mod 221
25 * 5 = 125 mod 221
125 * 5 = 183 mod 221
183 * 5 = 31 mod 221
31 * 5 = 155 mod 221
155 * 5 = 112 mod 221
112 * 5 = 118 mod 221
118 * 5 = 148 mod 221
148 * 5 = 77 mod 221
77 * 5 = 164 mod 221
164 * 5 = 157 mod 221
157 * 5 = 122 mod 221
122 * 5 = 168 mod 221
168 * 5 = 177 mod 221
177 * 5 = 1 mod 221
1 * 5 = 5 mod 221
5 * 5 = 25 mod 221
25 * 5 = 125 mod 221
125 * 5 = 183 mod 221
183 * 5 = 31 mod 221
31 * 5 = 155 mod 221
155 * 5 = 112 mod 221
Therefore, 5^55 = 112 mod 221.
Now, we can improve this by using exponentiation by squaring; this is the famous trick wherein we reduce exponentiation to requiring only log b multiplications instead of b. Note that with the algorithm that I described above, the exponentiation by squaring improvement, you end up with the right-to-left binary method.
a1 = a reduced mod m
p = 1
while (b > 0) {
if (b is odd) {
p *= a1
p = p reduced mod m
}
b /= 2
a1 = (a1 * a1) reduced mod m
}
Thus, since 55 = 110111 in binary
1 * (5^1 mod 221) = 5 mod 221
5 * (5^2 mod 221) = 125 mod 221
125 * (5^4 mod 221) = 112 mod 221
112 * (5^16 mod 221) = 112 mod 221
112 * (5^32 mod 221) = 112 mod 221
Therefore the answer is 5^55 = 112 mod 221. The reason this works is because
55 = 1 + 2 + 4 + 16 + 32
so that
5^55 = 5^(1 + 2 + 4 + 16 + 32) mod 221
= 5^1 * 5^2 * 5^4 * 5^16 * 5^32 mod 221
= 5 * 25 * 183 * 1 * 1 mod 221
= 22875 mod 221
= 112 mod 221
In the step where we calculate 5^1 mod 221, 5^2 mod 221, etc. we note that 5^(2^k) = 5^(2^(k-1)) * 5^(2^(k-1)) because 2^k = 2^(k-1) + 2^(k-1) so that we can first compute 5^1 and reduce mod 221, then square this and reduce mod 221 to obtain 5^2 mod 221, etc.
The above algorithm formalizes this idea.
To add to Jason's answer:
You can speed the process up (which might be helpful for very large exponents) using the binary expansion of the exponent. First calculate 5, 5^2, 5^4, 5^8 mod 221 - you do this by repeated squaring:
5^1 = 5(mod 221)
5^2 = 5^2 (mod 221) = 25(mod 221)
5^4 = (5^2)^2 = 25^2(mod 221) = 625 (mod 221) = 183(mod221)
5^8 = (5^4)^2 = 183^2(mod 221) = 33489 (mod 221) = 118(mod 221)
5^16 = (5^8)^2 = 118^2(mod 221) = 13924 (mod 221) = 1(mod 221)
5^32 = (5^16)^2 = 1^2(mod 221) = 1(mod 221)
Now we can write
55 = 1 + 2 + 4 + 16 + 32
so 5^55 = 5^1 * 5^2 * 5^4 * 5^16 * 5^32
= 5 * 25 * 625 * 1 * 1 (mod 221)
= 125 * 625 (mod 221)
= 125 * 183 (mod 183) - because 625 = 183 (mod 221)
= 22875 ( mod 221)
= 112 (mod 221)
You can see how for very large exponents this will be much faster (I believe it's log as opposed to linear in b, but not certain.)
/* The algorithm is from the book "Discrete Mathematics and Its
Applications 5th Edition" by Kenneth H. Rosen.
(base^exp)%mod
*/
int modular(int base, unsigned int exp, unsigned int mod)
{
int x = 1;
int power = base % mod;
for (int i = 0; i < sizeof(int) * 8; i++) {
int least_sig_bit = 0x00000001 & (exp >> i);
if (least_sig_bit)
x = (x * power) % mod;
power = (power * power) % mod;
}
return x;
}
5^55 mod221
= ( 5^10 * 5^10 * 5^10 * 5^10 * 5^10 * 5^5) mod221
= ( ( 5^10) mod221 * 5^10 * 5^10 * 5^10 * 5^10 * 5^5) mod221
= ( 77 * 5^10 * 5^10 * 5^10 * 5^10 * 5^5) mod221
= ( ( 77 * 5^10) mod221 * 5^10 * 5^10 * 5^10 * 5^5) mod221
= ( 183 * 5^10 * 5^10 * 5^10 * 5^5) mod221
= ( ( 183 * 5^10) mod221 * 5^10 * 5^10 * 5^5) mod221
= ( 168 * 5^10 * 5^10 * 5^5) mod221
= ( ( 168 * 5^10) mod 221 * 5^10 * 5^5) mod221
= ( 118 * 5^10 * 5^5) mod221
= ( ( 118 * 5^10) mod 221 * 5^5) mod221
= ( 25 * 5^5) mod221
= 112
What you're looking for is modular exponentiation, specifically modular binary exponentiation. This wikipedia link has pseudocode.
Chinese Remainder Theorem comes to mind as an initial point as 221 = 13 * 17. So, break this down into 2 parts that get combined in the end, one for mod 13 and one for mod 17. Second, I believe there is some proof of a^(p-1) = 1 mod p for all non zero a which also helps reduce your problem as 5^55 becomes 5^3 for the mod 13 case as 13*4=52. If you look under the subject of "Finite Fields" you may find some good results on how to solve this.
EDIT: The reason I mention the factors is that this creates a way to factor zero into non-zero elements as if you tried something like 13^2 * 17^4 mod 221, the answer is zero since 13*17=221. A lot of large numbers aren't going to be prime, though there are ways to find large primes as they are used a lot in cryptography and other areas within Mathematics.
This is part of code I made for IBAN validation. Feel free to use.
static void Main(string[] args)
{
int modulo = 97;
string input = Reverse("100020778788920323232343433");
int result = 0;
int lastRowValue = 1;
for (int i = 0; i < input.Length; i++)
{
// Calculating the modulus of a large number Wikipedia http://en.wikipedia.org/wiki/International_Bank_Account_Number
if (i > 0)
{
lastRowValue = ModuloByDigits(lastRowValue, modulo);
}
result += lastRowValue * int.Parse(input[i].ToString());
}
result = result % modulo;
Console.WriteLine(string.Format("Result: {0}", result));
}
public static int ModuloByDigits(int previousValue, int modulo)
{
// Calculating the modulus of a large number Wikipedia http://en.wikipedia.org/wiki/International_Bank_Account_Number
return ((previousValue * 10) % modulo);
}
public static string Reverse(string input)
{
char[] arr = input.ToCharArray();
Array.Reverse(arr);
return new string(arr);
}
Jason's answer in Java (note i < exp).
private static void testModulus() {
int bse = 5, exp = 55, mod = 221;
int a1 = bse % mod;
int p = 1;
System.out.println("1. " + (p % mod) + " * " + bse + " = " + (p % mod) * bse + " mod " + mod);
for (int i = 1; i < exp; i++) {
p *= a1;
System.out.println((i + 1) + ". " + (p % mod) + " * " + bse + " = " + ((p % mod) * bse) % mod + " mod " + mod);
p = (p % mod);
}
}
Just provide another implementation of Jason's answer by C.
After discussing with my classmates, based on Jason's explanation, I like the recursive version more if you don't care about the performance very much:
For example:
#include<stdio.h>
int mypow( int base, int pow, int mod ){
if( pow == 0 ) return 1;
if( pow % 2 == 0 ){
int tmp = mypow( base, pow >> 1, mod );
return tmp * tmp % mod;
}
else{
return base * mypow( base, pow - 1, mod ) % mod;
}
}
int main(){
printf("%d", mypow(5,55,221));
return 0;
}
This is called modular exponentiation(https://en.wikipedia.org/wiki/Modular_exponentiation).
Let's assume you have the following expression:
19 ^ 3 mod 7
Instead of powering 19 directly you can do the following:
(((19 mod 7) * 19) mod 7) * 19) mod 7
But this can take also a long time due to a lot of sequential multipliations and so you can multiply on squared values:
x mod N -> x ^ 2 mod N -> x ^ 4 mod -> ... x ^ 2 |log y| mod N
Modular exponentiation algorithm makes assumptions that:
x ^ y == (x ^ |y/2|) ^ 2 if y is even
x ^ y == x * ((x ^ |y/2|) ^ 2) if y is odd
And so recursive modular exponentiation algorithm will look like this in java:
/**
* Modular exponentiation algorithm
* #param x Assumption: x >= 0
* #param y Assumption: y >= 0
* #param N Assumption: N > 0
* #return x ^ y mod N
*/
public static long modExp(long x, long y, long N) {
if(y == 0)
return 1 % N;
long z = modExp(x, Math.abs(y/2), N);
if(y % 2 == 0)
return (long) ((Math.pow(z, 2)) % N);
return (long) ((x * Math.pow(z, 2)) % N);
}
Special thanks to #chux for found mistake with incorrect return value in case of y and 0 comparison.