04-18-2013 11:56 AM - edited 04-18-2013 11:57 AM
Maybe we are talking about different things. In a large number of tosses the probability of getting exactly 10 heads in 1024 tosses is 50%. To get the probability of getting 10 or MORE in a row we must add to that the probability of getting 11, 12, 13, etc. in a row, so it is somewhat greater than 50%. It is not 40% as you say.
Look at it this way:
In 1 tosses half the time you will get a head.
In 2 tosses one-quarter the time you will get 2 heads in a row. (Do the binary tree on paper.)
In 3 tosses one-eight of the time you will get 3 heads in a row.
In 4 tosses one-sixteenth of the time you will get 4 heads in a row.
...
In 10 tosses one-1024th of the time you will get 10 heads in a row.
Another way of looking at that last line is "In a large number of tosses, the probability of getting 10 heads in a row is 1/1024." No?
What I was really trying to prove is that even if you have a streak of 100 heads in a row, the probability the next one will be heads (or tails for that matter) is 0.5. Agreed? My program was showing 0.4 which MUST BE a coding error. I think my previous post proved that, since I got 1067 streaks of 10 or more heads in 2^20 tosses.
Ed
04-18-2013 12:05 PM - edited 04-18-2013 12:07 PM
By the way, this is turning out to be more fun than I expected. Thanks all.
On the subject of local variables, I want to say the following:
I came from the text-based programming world: C, Visual Basic, assembler, etc. I picked up LabVIEW several years ago. In C, for example, a “local variable” is a variable which has a “scope” which is “local” to a function (which is called a “subroutine” in other languages). A “global” variable’s scope is for the entire program. (It needs to be declared “extern” in other modules within the program.) What LabVIEW terms a “local variable” to me is essentially a “global”, and I’m using it as such. When I use a local variable in LabVIEW I’m using it as I would a global. The local variable is used just like if I am writing its name in many places in a C program. In C one must be careful in using global variables if interrupts are used which can modify it, but that’s the main caution. (Windows programs are inerrupt-driven, which is why globals are frowned upon and must be used carefully. Better to pass them “by value” to functions, for example.) But I don’t see the big deal in using local (aka, global) variables in LabVIEW. It makes perfect sense and is more readable to me. I just need to be careful because LabVIEW code executes in parallel, unless forced not to, which can cause race conditions and unintended results. I'm aware of that, of course.
Ed
04-18-2013 12:29 PM - edited 04-18-2013 12:30 PM
04-18-2013 12:44 PM - edited 04-18-2013 12:45 PM
04-18-2013 01:06 PM
@Edjsch wrote:
What LabVIEW terms a “local variable” to me is essentially a “global”, and I’m using it as such.
In LabVIEW, a local variable refers to the value a front panel object (control or indicator). It is not a "variable" in the classic sense of text based languages. Since labels of front panel objects can occur in duplicate, you can have local variables with the same name, but containing different data. The front panel is updated asynchronously, so there is also a transfer buffer that holds the value until the panel is updated. Local variables always involve additional data copies in memory, which could be significant when dealing with large data structures. IMHO, calculations belong entirely on the diagram. Local variables should mainly be used for UI interactions. While not entirely true, you can say that in LabVIEW "the wire is the variable". 😄
A shift register is one of the most efficient structures in LabVIEW, because it can typcally operate fully "in place" doing "read,modify,write" operations (read from the left terminal, modify the value with each iteration and write the result back into the same location by wiring to the right terminal).
04-18-2013 01:40 PM
@Edjsch wrote:
...
In 2 tosses one-quarter the time you will get 2 heads in a row. (Do the binary tree on paper.)
...
In 10 tosses one-1024th of the time you will get 10 heads in a row.
Another way of looking at that last line is "In a large number of tosses, the probability of getting 10 heads in a row is 1/1024." No?
I disagree with this.
If you toss 10 coins at a time (1024 times) then they are independant events where each toss is unrelated to the others.
If you toss 1024 coins and look for a "streak of 10" then the tosses are interleaved.
You can see this if you look at a smaller subset for testing such as:
In 2 tosses one-quarter the time you will get 2 heads in a row. (Do the binary tree on paper.)
So you would be saying in four coin tosses you would expect 2 heads in a row 1/4 of the time (%25).
0000
0001
0010
0011 <
0100
0101
0110 <
0111 <
1000
1001
1010
1011 <
1100 <
1101 <
1110 <
1111 <
16 possible combinations but 8 chances to have two or more in a row = %50.
The percentages being different indicate they are not the same yes?
04-18-2013 01:48 PM
I get what you're saying. And looking at the wire as "the variable" is a great analogy. However, a shift register must have AT LEAST ONE duplicate copy of the variable, to keep the value of the previous iteration. So one "local variable" (in the LabVIEW sense) is equivalent to a shift register. More than that, the shift register wins, at least in memory usage. Since memory is so cheap and abundant, I often opt for the local variable, because, IMHO, the block diagram often looks cleaner. Even NI says one use of locals is to avoid running wires all over the place, and is especially true in large block diagrams.
Ed
04-18-2013 01:59 PM
@Edjsch wrote:
However, a shift register must have AT LEAST ONE duplicate copy of the variable, to keep the value of the previous iteration.
No. You can update the value stored in the shift register, overwriting the previous value and reusing the same memory location. For example, inside your loop you want to increment the shift register value on some iterations, otherwise the value is passed through unchanged. When the value is unchanged, that memory is left alone completely - no copies. When you increment the value, that operation can happen in-place - the result of the increment is stored back to the original location. Again, no copy. A second memory location is needed only when you need access to both the current and previous values simultaneously.
04-18-2013 02:01 PM
You are proving what I am saying. You showed that in the 4 tosses there are 4 heads in a row 1 time out of 16. (Those 16 values are the only possible values, but on each and every series of tosses it is unlikely to get those 16 and only those 16 values. This is where "probability theory" comes in.)
My formula is for the "probability" of getting 4 heads in a row (in any large number of tosses), which is 1/(2^4) or 1/16.
Likewise, the probability of getting 10 heads in a row in a million tosses is 1/1024. So roughly every 1024 toses, one-half of them will have 10 heads in a row. (This is where "at least" or "exactly" 10 gets a little dicey.). So 1 milliion / 1024 ~= 1000. Therefore I would bet you that in a million tosses there would be very close to 1000 streaks of 10 heads in a row.
04-18-2013 02:04 PM - edited 04-18-2013 02:06 PM
You said, "You can update the value stored in the shift register, overwriting the previous value and reusing the same memory location."
Yes, that's true. But the SR is an extra memory location, since the control or indicator itself the FIRST memory storage location, and the shift register or one local variable the second? This may be a matter of semantics.