What programming language you start with really all depends on where you want to go with programming/coding. The great thing about this field is that there are an absolute abundance of smaller fields that you can go into, all using programming in their own unique ways. For web applications, a good start would be with HTML and later moving your way through CSS, JavaScript, JQuery, PHP, SQL, and any of the JavaScript libraries. Ruby is also a popular choice, so I would recommend checking that out too. For more scientific fields or areas with more machine learning and A.I., Python is generally a great place to start as it is widely used in that field of study. C++ is also a very useful language to know for that, but it can be a little more challenging for beginners. For game and application design, languages such as C#, C, Swift, Kotlin, and Java are most often used for that.
Description
Stochastic computing, first introduced by the noted scientist John von Neumann in 1953, is a collection of techniques that represent continuous values (for example probabilities between 0 and 1) using streams of random bits. The bits in the stream represent the probabilities. Complex computations can then be computed over these stream by applying simple bit-wise operations.
For example, given two probabilities p and q, using 8 bits, to represent the probabilities 0.5 and 0.25:
10011010
01010000
To calculate p x q we apply the logical AND over the bitstream:
00010000
Yielding 1/8, or 12.5%, the correct value. For an 8-bit stream, this is the smallest unit of precision we can calculate. To increase precision we must increase the size of the bitstream.
This approach has a few benefits in a noisy environment, most importantly a tolerance for loss (for example in transmission) and better fidelity over various bit lengths. However, precision comparable to a standard binary computer requires a significant amount of data - 500 bits in a stochastic computer to get to 32-bit precision in a binary computer.
Your challenge today is to build a basic stochastic computer for probabilistic inputs, supporting the four major arithmetic operations:
Addition
Subtraction
Multiplication
Division
Be sure to measure the precision and fidelity of your machine, I encourage you to explore the tradeoffs between space and accuracy.
Solution
in Java
public class Stochastic {
private static double limit = 1 << 4;
public static void main(String... args) {
int[] a = IntStream.generate(() -> Math.random() < 0.5 ? 1 : 0).limit((long) limit).toArray();
int[] b = IntStream.generate(() -> Math.random() < 0.25 ? 1 : 0).limit((long) limit).toArray();
Note.setSeperator("").setTags("", "").writenl(a).writenl(b)
.writenl(bits(a) / limit + " + " + bits(b) / limit + " = " + add(a, b) / limit)
.writenl(bits(a) / limit + " - " + bits(b) / limit + " = " + sub(a, b) / limit)
.writenl(bits(a) / limit + " * " + bits(b) / limit + " = " + mul(a, b) / limit);
limit = 1 << 3;
a = new int[]{1,0,0,1,1,0,1,0};
b = new int[]{0,1,0,1,0,0,0,0};
Note.setSeperator("").setTags("", "").writenl(a).writenl(b)
.writenl(bits(a) / limit + " + " + bits(b) / limit + " = " + add(a, b) / limit)
.writenl(bits(a) / limit + " - " + bits(b) / limit + " = " + sub(a, b) / limit)
.writenl(bits(a) / limit + " * " + bits(b) / limit + " = " + mul(a, b) / limit);
}
private static int add(int[] a, int[] b) {
return IntStream.range(0, a.length)
.map(i -> ((a[i] & b[i]) << 1) | (a[i] ^ b[i]))
.sum();
}
private static int sub(int[] a, int[] b) {
return IntStream.range(0, a.length)
.map(i -> ~(a[i] & b[i]) & a[i])
.sum();
}
private static int mul(int[] a, int[] b) {
return IntStream.range(0, a.length)
.map(i -> a[i] & b[i])
.sum();
}
private static int div(int[] a, int[] b) {
State q = new State().toFalse();
return IntStream.range(0, a.length)
.map(i -> {
switch ((a[i] << 1) + b[i]) {
case 0: return q.state();
case 1: return q.toFalse().state();
case 2: return q.toTrue().state();
case 3: return q.flip().state();
default: return 0;
}})
.sum();
}
private static int bits(int[] a) {
return Arrays.stream(a).sum();
}
}
class State {
private int state = 0;
State toTrue(){ state = 1; return this; }
State toFalse(){ state = 0; return this; }
State flip(){ state ^= 1; return this; }
int state(){ return state; }
}
Output
1110111100101111 (12/16)
1000000101000010 (4/16)
0.75 + 0.25 = 1.0
0.75 - 0.25 = 0.5625
0.75 * 0.25 = 0.1875
0.75 / 0.25 = 0.75
10011010
01010000
0.5 + 0.25 = 0.75
0.5 - 0.25 = 0.375
0.5 * 0.25 = 0.125
0.5 / 0.25 = 0.75
Stochastic computing, first introduced by the noted scientist John von Neumann in 1953, is a collection of techniques that represent continuous values (for example probabilities between 0 and 1) using streams of random bits. The bits in the stream represent the probabilities. Complex computations can then be computed over these stream by applying simple bit-wise operations.
For example, given two probabilities p and q, using 8 bits, to represent the probabilities 0.5 and 0.25:
10011010
01010000
To calculate p x q we apply the logical AND over the bitstream:
00010000
Yielding 1/8, or 12.5%, the correct value. For an 8-bit stream, this is the smallest unit of precision we can calculate. To increase precision we must increase the size of the bitstream.
This approach has a few benefits in a noisy environment, most importantly a tolerance for loss (for example in transmission) and better fidelity over various bit lengths. However, precision comparable to a standard binary computer requires a significant amount of data - 500 bits in a stochastic computer to get to 32-bit precision in a binary computer.
Your challenge today is to build a basic stochastic computer for probabilistic inputs, supporting the four major arithmetic operations:
Addition
Subtraction
Multiplication
Division
Be sure to measure the precision and fidelity of your machine, I encourage you to explore the tradeoffs between space and accuracy.
Solution
in Java
public class Stochastic {
private static double limit = 1 << 4;
public static void main(String... args) {
int[] a = IntStream.generate(() -> Math.random() < 0.5 ? 1 : 0).limit((long) limit).toArray();
int[] b = IntStream.generate(() -> Math.random() < 0.25 ? 1 : 0).limit((long) limit).toArray();
Note.setSeperator("").setTags("", "").writenl(a).writenl(b)
.writenl(bits(a) / limit + " + " + bits(b) / limit + " = " + add(a, b) / limit)
.writenl(bits(a) / limit + " - " + bits(b) / limit + " = " + sub(a, b) / limit)
.writenl(bits(a) / limit + " * " + bits(b) / limit + " = " + mul(a, b) / limit);
limit = 1 << 3;
a = new int[]{1,0,0,1,1,0,1,0};
b = new int[]{0,1,0,1,0,0,0,0};
Note.setSeperator("").setTags("", "").writenl(a).writenl(b)
.writenl(bits(a) / limit + " + " + bits(b) / limit + " = " + add(a, b) / limit)
.writenl(bits(a) / limit + " - " + bits(b) / limit + " = " + sub(a, b) / limit)
.writenl(bits(a) / limit + " * " + bits(b) / limit + " = " + mul(a, b) / limit);
}
private static int add(int[] a, int[] b) {
return IntStream.range(0, a.length)
.map(i -> ((a[i] & b[i]) << 1) | (a[i] ^ b[i]))
.sum();
}
private static int sub(int[] a, int[] b) {
return IntStream.range(0, a.length)
.map(i -> ~(a[i] & b[i]) & a[i])
.sum();
}
private static int mul(int[] a, int[] b) {
return IntStream.range(0, a.length)
.map(i -> a[i] & b[i])
.sum();
}
private static int div(int[] a, int[] b) {
State q = new State().toFalse();
return IntStream.range(0, a.length)
.map(i -> {
switch ((a[i] << 1) + b[i]) {
case 0: return q.state();
case 1: return q.toFalse().state();
case 2: return q.toTrue().state();
case 3: return q.flip().state();
default: return 0;
}})
.sum();
}
private static int bits(int[] a) {
return Arrays.stream(a).sum();
}
}
class State {
private int state = 0;
State toTrue(){ state = 1; return this; }
State toFalse(){ state = 0; return this; }
State flip(){ state ^= 1; return this; }
int state(){ return state; }
}
Output
1110111100101111 (12/16)
1000000101000010 (4/16)
0.75 + 0.25 = 1.0
0.75 - 0.25 = 0.5625
0.75 * 0.25 = 0.1875
0.75 / 0.25 = 0.75
10011010
01010000
0.5 + 0.25 = 0.75
0.5 - 0.25 = 0.375
0.5 * 0.25 = 0.125
0.5 / 0.25 = 0.75
Comments
Post a Comment