How are 3-state cellular automata rules generated? - c

Let's limit the neighborhood to n=1 (which means we always need 3 cells to evaluate the next-gen cell).
Here's an example of a 2 state rule. Note that the upper row of the rules are generated in a particular order, whereas the lower row is the bit representation of the number 30.
I cannot find a single visualization of the equivalent for a 3 state CA. Following the logic of 2 state CA, it should contain 27 possible outcomes, but I have no clue in which order they should be generated. The lower row should be 30 in ternary (with leading zeroes to occupy a total of 27 positions).
Is there a general algorithm for generating these permutations in the conventional order of CAs (regardless of the number of states)?
Thank you very much in advance and sorry if the question is stupid. :(

What you are using is called Wolfram's code (from Stephen Wolfram) that is used for elementary CAs.
If you use more states or bigger neighborhoods then it is sufficient to extend it naturally.
Your question is not stupid.
For three states, this will give you ternary numbers. First write all the three digits number in ternary (descending order):
222, 221, 220, 212, 211, 210, 202, 201, 200, 122, 121, 120, 112, 111, 110, 102, 101, 100, 022, 021, 020, 012, 011, 010, 002, 001, 000
There are 27 of them 3^3, and 222_3 = 26, 221_3 = 25, 001_3 = 1, 000_3 = 0
Now decompose 30 onto base 3 27-digits number: 30 = 1*3^3+ 1*3^1, so there is only two digits equals to 1, the fourth and the second (from the right), here is rule 30 for radius-1 3-states CA:
000000000000000000000001010
This CA has a very different behavior than rule 30 radius-1 2-states CA.
Here is rule 33 for radius-1 3-states (33 = 1*3^3 + 2*3^1):
000000000000000000000001020
So for n,r, enumerate in descending order all 2r+1 digits numbers in base n and associate for each of them a value in [0,n[.

Related

Understanding input and labels in word2vec (TensorFlow)

I am trying to properly understand the batch_input and batch_labels from the tensorflow "Vector Representations of Words" tutorial.
For instance, my data
1 1 1 1 1 1 1 1 5 251 371 371 1685 ...
... starts with
skip_window = 2 # How many words to consider left and right.
num_skips = 1 # How many times to reuse an input to generate a label.
Then the generated input array is:
bach_input = 1 1 1 1 1 1 5 251 371 ....
This makes sense, starts from after 2 (= window size) and then continuous. The labels:
batch_labels = 1 1 1 1 1 1 251 1 1685 371 589 ...
I don't understand these labels very well. There are supposed to be 4 labels for each input right (window size 2, on each side). But the batch_label variable is the same length.
From the tensorflow tutorial:
The skip-gram model takes two inputs. One is a batch full of integers
representing the source context words, the other is for the target
words.
As per the tutorial, I have declared the two variables as:
batch = np.ndarray(shape=(batch_size), dtype=np.int32)
labels = np.ndarray(shape=(batch_size, 1), dtype=np.int32)
How should I interpret the batch_labels?
There are supposed to be 4 labels for each input right (window size 2, on each side). But the batch_label variable is the same length.
The key setting is num_skips = 1. This value defines the number of (input, label) tuples each word generates. See the examples with different num_skips below (my data sequence seems to be different from yours, sorry about that).
Example #1 - num_skips=4
batch, labels = generate_batch(batch_size=8, num_skips=4, skip_window=2)
It generates 4 labels for each word, i.e. uses the whole context; since batch_size=8 only 2 words are processed in this batch (12 and 6), the rest will go into the next batch:
data = [5239, 3084, 12, 6, 195, 2, 3137, 46, 59, 156, 128, 742, 477, 10572, ...]
batch = [12 12 12 12 6 6 6 6]
labels = [[6 3084 5239 195 195 3084 12 2]]
Example #2 - num_skips=2
batch, labels = generate_batch(batch_size=8, num_skips=2, skip_window=2)
Here you would expect each word appear twice in the batch sequence; the 2 labels are randomly sampled from 4 possible words:
data = [5239, 3084, 12, 6, 195, 2, 3137, 46, 59, 156, 128, 742, 477, 10572, ...]
batch = [ 12 12 6 6 195 195 2 2]
labels = [[ 195 3084 12 195 3137 12 46 195]]
Example #3 - num_skips=1
batch, labels = generate_batch(batch_size=8, num_skips=1, skip_window=2)
Finally, this setting, same as yours, produces exactly one label per each word; each label is drawn randomly from the 4-word context:
data = [5239, 3084, 12, 6, 195, 2, 3137, 46, 59, 156, 128, 742, 477, 10572, ...]
batch = [ 12 6 195 2 3137 46 59 156]
labels = [[ 6 12 12 195 59 156 46 46]]
How should I interpret the batch_labels?
Each label is the center word to be predicted from the context. But the generated data may take not all (context, center) tuples, depending on the settings of the generator.
Also note that the train_labels tensor is 1-dimensional. Skip-Gram trains the model to predict any context word from the given center word, not all 4 context words at once. This explains why all training pairs (12, 6), (12, 3084), (12, 5239) and (12, 195) are valid.

Closeness score to a target array of numbers

It's hard to know what terms to search for on stackoverflow for this problem. Say you have a target array of numbers like [100, 250, 400, 60]
I want to be able to score the closeness other arrays have to this target based on a threshold / error bars of say 10. So for example, the array:
[90, 240, 390, 50] would get a high score (or positive match result) because of the error bars.
The order matters, so
[60, 400, 250, 100] would get zero score (or negative match result)
The arrays can be different sizes so
[33, 77, 300, 110, 260, 410, 60, 99, 23] would get good score or positive match result.
A good way to think about the problem is to imagine these numbers are frequencies of musical notes like C,G,E,F and I'm trying to match a sequence of notes against a target.
Searching stackoverflow I'm not sure is this post will work, but it's close:
Compare difference between multiple numbers
Update 17th Jan 2015:
I failed to mention a scenario that might affect current answers. If the array has noise between those target numbers, I still want to find a positive match. For example [33, 77, 300, 110, 260, 300, 410, 40, 60, 99, 23].
I believe what you're looking for is sequence similarity.
You can read about them on this wikipedia page. Your case seems fit to local alignment category. There's some algorithm you can choose :
Needleman–Wunsch algorithm
Levenshtein distance
However, since these algorithms compare strings, you have to design your own scoring rule when inserting, deleting or comparing numbers.
Sounds like what you're looking for is the RMS error, where RMS is the square Root of the Mean Squared error. Let me illustrate by example. Assume the target array is [100, 250, 400, 60] and the array to be scored is [104, 240, 410, 55]
First compute the difference values, i.e. the errors
100 250 400 60
-104 -240 -410 -55
---- ---- ---- ---
-4 10 -10 5
Then square the errors to get 16 100 100 25. Compute the mean of the squared errors
(16 + 100 + 100 + 25) / 4 = 60.25
And finally, take the square root sqrt(60.25) = 7.76
When the arrays are different sizes, you can speed things up by only computing the RMS error if the first value is within a certain threshold, say +- 30. Using the example [33, 77, 300, 110, 260, 410, 60, 99, 23], there would only be two alignments to check, because with the other alignments the first number is more than 30 away from 100
33 77 300 110 260 410 60 99 23
100 250 400 60 --> RMS score = 178
100 250 400 60 --> RMS score = 8.7
Low score wins!

Total Comparisons of Sorting Algorithms to Complete Sort

I want to find the total comparisons for sorting n elements in an array using different sorting algorithms. I don't want to do it manually (in case the number of elements in the array is considerably large). Is there a "formula" to calculate the comparisons for each of the sorting algorithms listed below if for example there is 8 elements in an array containing the following elements [3,24,66,34,8,-5,42,80]? How can I find the comparisons for each?
1) Merge Sort
For example, if I use Merge sort manually in order to find the total numbers of
comparisons for 8 elements, this is what I get:
3, 24, 66, 34, 8, -5, 42, 80
3, 24, 66, 34 8, -5, 42, 80
3, 24 66, 34 8, -5 42, 80
3 24 66 34 8 -5 42 80
3, 24 34, 66 -5, 8 42, 80
3, 24, 34, 66 -5, 8, 42, 80
-5, 3, 8, 24, 34, 42, 66, 80
Total number of comparisons needed to sort this array = 15
I would like to be able to do this using a formula, if possible, not manually.
2) Insertion sort
This is not an easy task, as it can depend on details of the algorithm implementation, and also is not a pure function of n.
Actually, what you get is a distribution of values of the number of comparisons, depending on the permutation of the input. Usually, one distinguishes the best case (least number of comparison), the worst case (largest number) and the average case (mathematical expectation when you assume the respective probabilities of the input permutations).
These numbers can be obtained by reasoning on the program, but this is usually a difficult task (even daunting for the average case), often solved with approximations.
Anyway, you can obtain it empirically by instrumenting your program: declare a counter variable, and increment it at the same time as a comparison is made.
I recommend you to do what follows as an exercise:
instrument the code as I said,
take the sequence of the n first integers;
generate all possible permutations of the input (there will be exactly n! possibilities - as long as n remains small, say n up to 10, this remains manageable, 10!=3628800) and run the algorithm on each;
(alternatively you can fill the array with random numbers and repeat many times);
accumulate the histogram of the number of comparisons (for every possible number of comparisons count how many permutations achieve it),
observe and compare the histograms of the different algorithms.
Even though n will remain modest, you will observe the best and worst cases, and with more care, the central trend and the spread. This should be instructive.
Using the same methodology, you can also observe the number of element displacements.
It is impossible, as the exact number depends on the input. This why you have optimistic complexity, pessimistic, and average sometimes also called expected. The prominent example is basic implementation of quick sort which has pessimistic complexity O(n^2). On the other hand optimistic case for bubble sort is O(n). More examples: http://en.wikipedia.org/wiki/Best,_worst_and_average_case#Sorting_algorithms.
The only thing you can do is to compute it per problem instance, for example by tapping into comparison function. Although, I am not sure if per-instance values are very meaningful.
Usually people do not make this kind of calculation. They are interested in evaluating the complexity of the algorithm, i.e., "asymptotically
How the number of comparisons increases with the size of the input"
For instance, merge sort grows (in average) with O(n log n). This means that the number of comparisons of merge sort is not worse than n log n where n is the size of the input. There are some methods to arrive to this expression, namely master theorem or tree method.
Actually, one can prove that no algorithm based only on comparisons cannot make less comparisons than n log n. This is the so-called comparison model! comparison algorithms
However, sorting can be done in linear time, depending on the type of your set, for instance using counting sort - a kind of histogram.

Different bases for radix sort in C

I am having a difficult time understanding radix sort. I have no problems implementing code to work with bases of 2 or 10. However, I have an assignment that requires a command line argument to specify the radix. The radix can be anywhere from 2 - 100,000. I have spent around 10 hours trying to understand this problem. I am not asking for a direct answer, because this is homework. However, if anyone can shed some light on this, please do.
A few things I don't understand. What is the point of having base 100,000? How would that even work. I understand having a base for every letter of the alphabet, or every number 1-9. I just can't seem to wrap my head around this concept.
I'm sorry if I haven't been specific enough.
A number N in any base B is just a series of digits in the range [0, B-1]. Since we don't have enough symbols to represent all the digits in a "normal" human writing system, don't think about how it's written in characters. You'll just need to know that the digits are stored/written separately
For example 255 in base 177 is a 2-digit number in which the first digit has value 1 and the second digit has value 78 since 25510 = 1×1771 + 78×1770. If some culture uses this base they'll have 177 distinct symbols for the digits and they write it in only 2 digits. Since we only have 10 symbols we'll need to define some symbol to delimit the digits, which is often :. As you can see from Wolfram Alpha, 25510 = 1:78177
Note that not all people count in base 10. There exists cultures that count in base 4, 5, 6, 8, 12, 15, 16, 20, 24, 27, 32, 36, 60... so they'll have more or less symbols than most of us. However among the non-decimal bases, only base 20, 12 and 60 are most commonly used nowadays.
In base 100000 it's the same. 1234567890987654321 will be a 4-digit number written as symbols with value 1234, 56789, 9876, 54321 in order
I was about to explain it in a comment, but basically you're talking about what we sometimes call "modular arithmetic." Each digit is {0...n-1} and represents that times nk, where k is the position. 255 in decimal is 5×100 + 5×101 + 2×102.
So, your 255 base 177 is hard to represent, but there's a 1 in the 177s place (177×101) and 78 in the 1s (177×100) place.
As a general pseudocode algorithm, you want something like...
n = input value
digits = []
while n > 1
quotient = n / base (as an integer)
digits += quotient
remainder = n - quotient * base
n = remainder
And you might need to check the final remainder, in case something has gone wrong.
Of course, how you represent those digits is another story. MIME is contains semi-standard way for handling up through Base-64, for example.
If it was me, I'd just delimit the digits and make it clear that's the representation, but there's all of Unicode, if you want to mess around with hexadecimal-like extensions...

How to get an evenly distributed sample from Perl array values?

I have an array containing many values between 0 and 360 (like degrees in a circle), but unevenly distributed:
1,45,46,47,48,49,50,51,52,53,54,55,100,120,140,188, 210, 280, 355
Now I need to reduce those values to e.g. 4 only, but as evenly as possible distributed values.
How to do that?
Thanks,
Jan
Put the numbers on a circle, like a clock. Now construct a logical cross, say at 12, 3, 6, and 9 o’clock. Put the 12 at the first number. Now find what numbers would be nearest to 3, 6, and 9 o’clock, and record the sum of those three numbers’ distances next to the first number.
Iterate by rotating the top of your cross — the 12 o’clock point — clockwise until it exactly lines up with the next number. Again measure how far the nearest numbers are to each of your three other crosspoints, and record that score next to this current 12 o’clock number.
Repeat until you reach your 12 o’clock has rotated all the way to the original 3 o’clock, at which point you’re done. Whichever number has the lowest sum assigned to it determines the winning configuration.
This solution generalizes to any range of values R and any number N of final points you wish to reduce the set to. Each point on the “cross” is R/N away from each other, and you need only rotate until the top of your cross reaches where the next arm was in the original position. So if you wanted 6 points, you would have a 6-pointed cross, each 60 degrees apart instead of a 4-pointed cross each 90 degrees apart. If your range is different, you still do the same sort of operation. That way you don’t need a physical clock and cross to implement this algorithm: it works for any R and N.
I feel bad about this answer from a Perl perspective, as I’ve not managed to include any dollar signs in the solution. :)
Use a clustering algorithm to divide your data into evenly distributed partitions. Then grab a random value from each cluster. The following $datafile looks like this:
1 1
45 45
46 46
...
210 210
280 280
355 355
First column is a tag, second column is data. Running the following with $K = 4:
use strict; use warnings;
use Algorithm::KMeans;
my $datafile = $ARGV[0] or die;
my $K = $ARGV[1] or 0;
my $mask = 'N1';
my $clusterer = Algorithm::KMeans->new(
datafile => $datafile,
mask => $mask,
K => $K,
terminal_output => 0,
);
$clusterer->read_data_from_file();
my ($clusters, $cluster_centers) = $clusterer->kmeans();
my %clusters;
while (#$clusters) {
my $cluster = shift #$clusters;
my $center = shift #$cluster_centers;
$clusters{"#$center"} = $cluster->[int rand( #$cluster - 1)];
}
use YAML; print Dump \%clusters;
returns this:
120: 120
199: 188
317.5: 355
45.9166666666667: 46
First column is the center of the cluster, second is the selected value from that cluster. The centers' distance to one another should be maximized according to the Expectation Maximization algorithm.

Resources