25package umontreal.ssj.util;
35public class ArithmeticMod {
38 private static final double two17 = 131072.0;
39 private static final double two53 = 9007199254740992.0;
42 private ArithmeticMod() {
60 public static double multModM(
double a,
double s,
double c,
double m) {
63 if (v >= two53 || v <= -two53) {
64 a1 = (int) (a / two17);
69 v = v * two17 + a * s + c;
72 if ((v -= a1 * m) < 0.0)
88 public static void matVecModM(
double A[][],
double s[],
double v[],
double m) {
90 double x[] =
new double[v.length];
91 for (i = 0; i < v.length; ++i) {
93 for (
int j = 0; j < s.length; j++)
94 x[i] =
multModM(A[i][j], s[j], x[i], m);
96 for (i = 0; i < v.length; ++i)
109 public static void matMatModM(
double A[][],
double B[][],
double C[][],
double m) {
113 double V[] =
new double[r];
114 double W[][] =
new double[r][c];
115 for (i = 0; i < c; ++i) {
116 for (j = 0; j < r; ++j)
119 for (j = 0; j < r; ++j)
122 for (i = 0; i < r; ++i) {
123 for (j = 0; j < c; ++j)
137 public static void matTwoPowModM(
double A[][],
double B[][],
double m,
int e) {
141 for (i = 0; i < A.length; i++) {
142 for (j = 0; j < A.length; ++j)
147 for (i = 0; i < e; i++)
160 public static void matPowModM(
double A[][],
double B[][],
double m,
int c) {
164 double W[][] =
new double[s][s];
167 for (i = 0; i < s; i++) {
168 for (j = 0; j < s; ++j) {
173 for (j = 0; j < s; ++j)
204 public static int multModM(
int a,
int s,
int c,
int m) {
205 int r = (int) (((
long) a * s + c) % m);
206 return r < 0 ? r + m : r;
218 public static void matVecModM(
int A[][],
int s[],
int v[],
int m) {
220 int x[] =
new int[v.length];
221 for (i = 0; i < v.length; ++i) {
223 for (
int j = 0; j < s.length; j++)
224 x[i] =
multModM(A[i][j], s[j], x[i], m);
226 for (i = 0; i < v.length; ++i)
240 public static void matMatModM(
int A[][],
int B[][],
int C[][],
int m) {
244 int V[] =
new int[r];
245 int W[][] =
new int[r][c];
246 for (i = 0; i < c; ++i) {
247 for (j = 0; j < r; ++j)
250 for (j = 0; j < r; ++j)
253 for (i = 0; i < r; ++i) {
254 for (j = 0; j < c; ++j)
272 for (i = 0; i < A.length; i++) {
273 for (j = 0; j < A.length; ++j)
278 for (i = 0; i < e; i++)
291 public static void matPowModM(
int A[][],
int B[][],
int m,
int c) {
295 int W[][] =
new int[s][s];
298 for (i = 0; i < s; i++) {
299 for (j = 0; j < s; ++j) {
304 for (j = 0; j < s; ++j)
335 public static long multModM(
long a,
long s,
long c,
long m) {
344 final long H = 2147483648L;
345 long a0, a1, q, qh, rh, k, p;
357 p = H * (s - k * qh) - k * rh;
359 p = (p + 1) % m + m - 1;
365 p -= k * (m - a1 * q);
368 p += a1 * (s - k * q);
370 p = (p + 1) % m + m - 1;
373 p = H * (p - k * qh) - k * rh;
375 p = (p + 1) % m + m - 1;
380 p -= k * (m - a0 * q);
383 p += a0 * (s - k * q);
385 p = (p + 1) % m + m - 1;
402 public static void matVecModM(
long A[][],
long s[],
long v[],
long m) {
404 long x[] =
new long[v.length];
405 for (i = 0; i < v.length; ++i) {
407 for (
int j = 0; j < s.length; j++)
408 x[i] =
multModM(A[i][j], s[j], x[i], m);
410 for (i = 0; i < v.length; ++i)
424 public static void matMatModM(
long A[][],
long B[][],
long C[][],
long m) {
428 long V[] =
new long[r];
429 long W[][] =
new long[r][c];
430 for (i = 0; i < c; ++i) {
431 for (j = 0; j < r; ++j)
434 for (j = 0; j < r; ++j)
437 for (i = 0; i < r; ++i) {
438 for (j = 0; j < c; ++j)
456 for (i = 0; i < A.length; i++) {
457 for (j = 0; j < A.length; ++j)
462 for (i = 0; i < e; i++)
475 public static void matPowModM(
long A[][],
long B[][],
long m,
int c) {
479 long W[][] =
new long[s][s];
482 for (i = 0; i < s; i++) {
483 for (j = 0; j < s; ++j) {
488 for (j = 0; j < s; ++j)
static void matVecModM(double A[][], double s[], double v[], double m)
Computes the result of and puts the result in v.
static void matMatModM(long A[][], long B[][], long C[][], long m)
Exactly like matMatModM(double[][],double[][],double[][],double) using double, but with long instead ...
static void matVecModM(int A[][], int s[], int v[], int m)
Exactly like matVecModM(double[][],double[],double[],double) using double, but with int instead of do...
static void matTwoPowModM(double A[][], double B[][], double m, int e)
Computes and puts the result in B.
static void matPowModM(double A[][], double B[][], double m, int c)
Computes and puts the result in B.
static double multModM(double a, double s, double c, double m)
Computes .
static void matPowModM(int A[][], int B[][], int m, int c)
Exactly like matPowModM(double[][],double[][],double,int) using double, but with int instead of doubl...
static void matVecModM(long A[][], long s[], long v[], long m)
Exactly like matVecModM(double[][],double[],double[],double) using double, but with long instead of d...
static void matMatModM(double A[][], double B[][], double C[][], double m)
Computes and puts the result in C.
static long multModM(long a, long s, long c, long m)
Computes .
static int multModM(int a, int s, int c, int m)
Computes .
static void matPowModM(long A[][], long B[][], long m, int c)
Exactly like matPowModM(double[][],double[][],double,int) using double, but with long instead of doub...
static void matTwoPowModM(int A[][], int B[][], int m, int e)
Exactly like matTwoPowModM(double[][],double[][],double,int) using double, but with int instead of do...
static void matTwoPowModM(long A[][], long B[][], long m, int e)
Exactly like matTwoPowModM(double[][],double[][],double,int) using double, but with long instead of d...
static void matMatModM(int A[][], int B[][], int C[][], int m)
Exactly like matMatModM(double[][],double[][],double[][],double) using double, but with int instead o...