Rev 13 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
13 | daniel-mar | 1 | package de.viathinksoft.immortable.gen5; |
2 | |||
14 | daniel-mar | 3 | /* |
4 | * gen4 hätte bei dieser stelle |
||
5 | * 1:02 h gebraucht. |
||
6 | * |
||
7 | * wie lange dauert es hier? |
||
8 | * 3:16 h |
||
9 | */ |
||
10 | |||
11 | import java.io.IOException; |
||
13 | daniel-mar | 12 | import java.math.BigInteger; |
13 | |||
14 | import de.viathinksoft.immortable.gen2.math.CRTException; |
||
15 | import de.viathinksoft.immortable.gen2.math.CoPrimeExpectedException; |
||
16 | |||
17 | // Generation 5: EXPERIMENTAL |
||
18 | // Versuch, "t"-Erzeugung für M6 zu realisieren |
||
19 | // Versuch, Geschwindigkeit drastisch zu steigen und Zeit für |
||
20 | // Neu-Berechnungen durch kontinuierliche Rechnung zu sparen. |
||
21 | // Nachteil: Rechenfehler können nun nicht mehr diagnostiziert werden, da Appended wird. |
||
22 | // Im Moment noch nicht MAX_INTEGER+1 tauglich (da es sowieso fraglich ist, ob String das aushält) |
||
23 | |||
24 | // Fehlschlag ... Die Zeit ist zu stark exponentiell und nicht wie erhofft linear |
||
25 | |||
26 | public class Gen5Test { |
||
27 | |||
28 | private static final BigInteger CONST_2 = new BigInteger("2"); |
||
29 | private static final BigInteger CONST_M2 = new BigInteger("-2"); |
||
30 | private static final BigInteger CONST_5 = new BigInteger("5"); |
||
31 | private static final BigInteger CONST_9 = new BigInteger("9"); |
||
32 | |||
33 | private static final BigInteger[][] lookUpCR = { |
||
34 | { BigInteger.valueOf(0), BigInteger.valueOf(5) }, |
||
35 | { BigInteger.valueOf(6), BigInteger.valueOf(1) }, |
||
36 | { BigInteger.valueOf(2), BigInteger.valueOf(7) }, |
||
37 | { BigInteger.valueOf(8), BigInteger.valueOf(3) }, |
||
38 | { BigInteger.valueOf(4), BigInteger.valueOf(9) } }; |
||
39 | |||
14 | daniel-mar | 40 | public static BigInteger pow(BigInteger x, BigInteger y) { |
41 | if (y.compareTo(BigInteger.ZERO) < 0) |
||
42 | throw new IllegalArgumentException(); |
||
43 | // z will successively become x^2, x^4, x^8, x^16, x^32... |
||
44 | BigInteger z = x; |
||
45 | BigInteger result = BigInteger.ONE; |
||
46 | byte[] bytes = y.toByteArray(); |
||
47 | for (int i = bytes.length - 1; i >= 0; i--) { |
||
48 | byte bits = bytes[i]; |
||
49 | for (int j = 0; j < 8; j++) { |
||
50 | if ((bits & 1) != 0) |
||
51 | result = result.multiply(z); |
||
52 | // short cut out if there are no more bits to handle: |
||
53 | if ((bits >>= 1) == 0 && i == 0) |
||
54 | return result; |
||
55 | z = z.multiply(z); |
||
56 | } |
||
57 | } |
||
58 | return result; |
||
59 | } |
||
13 | daniel-mar | 60 | |
14 | daniel-mar | 61 | public static void doIt(int init_u, BigInteger init_r, |
62 | BigInteger init_s, BigInteger init_t, int abbruch) |
||
63 | throws CoPrimeExpectedException, IOException { |
||
64 | |||
65 | Datenspeicherung ds = new Datenspeicherung(); |
||
66 | |||
13 | daniel-mar | 67 | int u = init_u; |
68 | BigInteger r_ = init_r; |
||
69 | BigInteger s_ = init_s; |
||
70 | BigInteger t = init_t; |
||
71 | |||
72 | final boolean want_m5 = false; |
||
73 | |||
74 | BigInteger p2pow = CONST_2.pow(u - 1); // TODO: leftshift |
||
75 | BigInteger p5pow = CONST_5.pow(u - 1); |
||
76 | |||
14 | daniel-mar | 77 | // test: r halb so klein halten |
78 | boolean wasMod2 = r_.mod(CONST_2).equals(BigInteger.ZERO); |
||
79 | r_ = r_.divide(CONST_2); |
||
80 | |||
13 | daniel-mar | 81 | while (true) { |
82 | BigInteger r = r_; |
||
83 | BigInteger s = s_; |
||
84 | |||
14 | daniel-mar | 85 | ds.add(t, r, s); |
86 | |||
13 | daniel-mar | 87 | if (want_m5) { |
88 | if (u == 1) { |
||
89 | t = CONST_5; |
||
90 | } else { |
||
91 | t = CONST_9.subtract(t); |
||
92 | } |
||
93 | } |
||
94 | |||
14 | daniel-mar | 95 | if (u == abbruch) { |
96 | ds.save("ds5_res.txt"); |
||
13 | daniel-mar | 97 | break; |
14 | daniel-mar | 98 | } |
13 | daniel-mar | 99 | |
100 | int rem = u % 4; |
||
101 | |||
102 | BigInteger x = null; |
||
103 | if (rem == 0) { |
||
104 | x = s.negate(); |
||
105 | } else if (rem == 1) { |
||
106 | x = s.multiply(CONST_2); |
||
107 | } else if (rem == 2) { |
||
108 | x = s; |
||
109 | } else if (rem == 3) { |
||
110 | x = s.multiply(CONST_M2); |
||
111 | } else { |
||
112 | } |
||
113 | |||
114 | // WARNUNG: MathUtils2 rechnet falsch/anders! |
||
115 | // t = MathUtils2.chineseRemainder(x.mod(CONST_5), CONST_5, |
||
116 | // r.mod(CONST_2), CONST_2); |
||
117 | |||
118 | // Auch zu lahm: |
||
119 | int remx = x.mod(CONST_5).intValue(); |
||
120 | |||
121 | // int remx; |
||
122 | // { |
||
123 | // String l = x.toString(); |
||
124 | // remx = Integer.parseInt(""+l.charAt(l.length()-1))%5; |
||
125 | // } |
||
126 | |||
14 | daniel-mar | 127 | // int remr = r.mod(CONST_2).intValue(); |
128 | int remr = (wasMod2) ? 0 : 1; // test: r halb so klein halten |
||
13 | daniel-mar | 129 | |
14 | daniel-mar | 130 | // int remr; |
131 | // { |
||
132 | // String l = r.toString(); |
||
133 | // if (l.endsWith("0") || l.endsWith("2") || l.endsWith("4") |
||
134 | // || l.endsWith("6") || l.endsWith("8")) { |
||
135 | // remr = 0; |
||
136 | // } else { |
||
137 | // remr = 1; |
||
138 | // } |
||
139 | // } |
||
13 | daniel-mar | 140 | |
14 | daniel-mar | 141 | // int remr = |
142 | // Math.abs(r.toString().endsWith(suffix)().mod(CONST_2).intValue()); |
||
13 | daniel-mar | 143 | |
144 | // Zu lahm: |
||
145 | // t = MathUtils.chineseRemainder(x, CONST_5, r, CONST_2); |
||
146 | // t = MathUtils.chineseRemainder(BigInteger.valueOf(remx), CONST_5, |
||
147 | // BigInteger.valueOf(remr), CONST_2); |
||
148 | t = lookUpCR[remx][remr]; |
||
149 | |||
14 | daniel-mar | 150 | // p5pow = CONST_5.pow(u); |
151 | // p5pow = pow(CONST_5, BigInteger.valueOf(u)); |
||
13 | daniel-mar | 152 | p5pow = p5pow.multiply(CONST_5); |
14 | daniel-mar | 153 | // r_ = t.multiply(p5pow).add(r).divide(CONST_2); |
13 | daniel-mar | 154 | |
14 | daniel-mar | 155 | // test: r halb klein halten |
156 | BigInteger[] dr = t.multiply(p5pow).divideAndRemainder(CONST_2); |
||
157 | r_ = dr[0].add(dr[1].add(r)); |
||
158 | wasMod2 = r_.mod(CONST_2).equals(BigInteger.ZERO); |
||
159 | r_ = r_.divide(CONST_2); |
||
160 | |||
13 | daniel-mar | 161 | // p2pow = CONST_2.pow(u); |
162 | // p2pow = p2pow.multiply(CONST_2); |
||
163 | p2pow = p2pow.shiftLeft(1); |
||
164 | s_ = t.multiply(p2pow).add(s).divide(CONST_5); |
||
165 | |||
166 | u++; |
||
167 | } |
||
168 | } |
||
169 | |||
14 | daniel-mar | 170 | public static void main(String[] args) throws CRTException, IOException { |
13 | daniel-mar | 171 | int a1 = 10000; |
14 | daniel-mar | 172 | int a2 = 40000; |
173 | |||
13 | daniel-mar | 174 | // ----------- |
175 | |||
176 | long zstVorher = System.currentTimeMillis(); |
||
177 | doIt(1, new BigInteger("3"), new BigInteger("1"), new BigInteger("6"), |
||
178 | a1); |
||
179 | long zstNachher = System.currentTimeMillis(); |
||
180 | long delta1 = (zstNachher - zstVorher); |
||
14 | daniel-mar | 181 | |
13 | daniel-mar | 182 | // ----------- |
14 | daniel-mar | 183 | |
13 | daniel-mar | 184 | zstVorher = System.currentTimeMillis(); |
185 | doIt(1, new BigInteger("3"), new BigInteger("1"), new BigInteger("6"), |
||
186 | a2); |
||
187 | zstNachher = System.currentTimeMillis(); |
||
188 | long delta2 = (zstNachher - zstVorher); |
||
14 | daniel-mar | 189 | |
13 | daniel-mar | 190 | // ----------- |
191 | |||
14 | daniel-mar | 192 | double c = ((double) delta2 / ((double) a2 / a1 * delta1)); |
13 | daniel-mar | 193 | |
14 | daniel-mar | 194 | // if (Immortable.isImmortable(new BigInteger(data.toString()))) { |
195 | // System.out.println("OK"); |
||
196 | // } else { |
||
197 | // System.out.println("FAIL"); |
||
198 | // } |
||
199 | |||
200 | System.out.println("Zeit benötigt: " + delta1 + " -> " + delta2 |
||
201 | + " (c=" + c + ")" + " ms"); |
||
13 | daniel-mar | 202 | } |
203 | } |