Do bitwise operations distribute over addition? - optimization

I'm looking at an algorithm I'm trying to optimize, and it's basically a lot of bit twiddling, followed by some additions in a tight feedback. If I could use carry-save addition for the adders, it would really help me speed things up, but I'm not sure if I can distribute the operations over the addition.
Specifically if I represent:
a = sa+ca (state + carry)
b = sb+cb
can I represent (a >>> r) in terms of s and c?
How about a | b and a & b?

Think about it...
sa = 1 ca = 1
sb = 1 cb = 1
a = sa + ca = 2
b = sb + cb = 2
(a | b) = 2
(a & b) = 2
(sa | sb) + (ca | cb) = (1 | 1) + (1 | 1) = 1 + 1 = 2 # Coincidence?
(sa & sb) + (ca & cb) = (1 & 1) + (1 & 1) = 1 + 1 = 2 # Coincidence?
Let's try some other values:
sa = 1001 ca = 1 # Binary
sb = 0100 cb = 1
a = sa + ca = 1010
b = sb + cb = 0101
(a | b) = 1111
(a & b) = 0000
(sa | sb) + (ca | cb) = (1001 | 0101) + (1 | 1) = 1101 + 1 = 1110 # Oh dear!
(sa & sb) + (ca & cb) = (1001 & 0101) + (1 & 1) = 0001 + 1 = 2 # Oh dear!
So, proof by 4-bit counter example that you cannot distribute AND or OR over addition.
What about '>>>' (unsigned or logical right shift). Using the last example values, and r = 1:
sa = 1001
ca = 0001
sa >>> 1 = 0101
ca >>> 1 = 0000
(sa >>> 1) + (ca >>> 1) = 0101 + 0000 = 0101
(sa + ca) >>> 1 = (1001 + 0001) >>> 1 = 1010 >>> 1 = 0101 # Coincidence?
Let's see whether that is coincidence too:
sa = 1011
ca = 0001
sa >>> 1 = 0101
ca >>> 1 = 0000
(sa >>> 1) + (ca >>> 1) = 0101 + 0000 = 0101
(sa + ca) >>> 1 = (1011 + 0001) >>> 1 = 1100 >>> 1 = 0110 # Oh dear!
Proof by counter-example again.
So logical right shift is not distributive over addition either.

No, you cannot distribute AND or OR over binary operators.
Explanation
Let P be a proposition where P: (A+B)&C = A&C + B&C
let us take A=2,B=3 =>A+B=5.
We are to prove A&C + B&C != (A+B)&C
A=2= 010
B=3= 011
let 010&C = x,
where x is some integer whose value is the resultant of bitwise AND of 010 and C
similarly 011&C = y, where y is some integer whose value is the resultant of bitwise AND of 011 and C
since we cannot say P holds for all C in the set of Natural numbers ( {0,1,...} ), consequently P is false.
In this case, take C=2=010
x=010 & 010 = 010 = 2
y=011 & 010 = 010 = 2
5&2=101 & 010 = 000 = 0
clearly, x+y!=0 , which means (A+B)&C != A&C + B&C.
Hence proved!

Related

Test if a permutation of a number exists in a collection

I'm trying to list all numbers with 3 digits where the individual digits sum to a given number.
So far I can return a list of all numbers using this Visual Basic code:
target = 17
i = 1
j = 1
k = 1
Do While i < 10
Do While j < 10
Do While k < 10
r = i + j + k
If r = target Then
If i <> j And j <> k And k <> i Then
lsNumbers.Add(i & j & k )
End If
End If
k += 1
Loop
If k = 10 Then k = 1
j += 1
Loop
If j = 10 Then j = 1
i += 1
Loop
But I want only unique, non repeating combinations.
For example for the target number 17:
179, 197, 269, 278, 287...
I want to be able to test the current number before I add it to the list, to check if it is a combination of a number already in the list - so 197 would fail because of 179, and 287 would fail because of 278
Observations
Just curious, is excluding the 0 digit on purpose?
To iterate through the possible digits, a well suited instruction pair is FOR NEXT. Definitely simpler than the DO WHILE that you used.
Loop
If k = 10 Then k = 1
Loop
If j = 10 Then j = 1
Upon loop completion, the iterator is sure to contain 10. The IF is redundant.
Solution
In order to check if a number, that obeys the condition, is unique in the sense that it is not composed of the same 3 digits as an already validated number, you could consult a 3-D array. If the new number corresponds to a non-zero element in this array, it means that the new number would be using the same digits as an earlier number. That's reason to reject it.
Next code runs in QBasic. You'll have no trouble rewriting it for Visual BASIC.
DIM r%(1 TO 9, 1 TO 9, 1 TO 9)
FOR i% = 1 TO 9
FOR j% = 1 TO 9
FOR k% = 1 TO 9
r%(i%, j%, k%) = 0
NEXT
NEXT
NEXT
target% = 17
FOR i% = 1 TO 9
FOR j% = 1 TO 9
FOR k% = 1 TO 9
IF i% + j% + k% = target% THEN
IF r%(i%, j%, k%) = 0 THEN
PRINT i% * 100 + j% * 10 + k%; " ";
r%(i%, j%, k%) = 1 ' Could do without this one because of the ascending order
r%(i%, k%, j%) = 1
r%(j%, i%, k%) = 1
r%(j%, k%, i%) = 1
r%(k%, i%, j%) = 1
r%(k%, j%, i%) = 1
END IF
END IF
NEXT
NEXT
NEXT
This is my output of valid numbers:
179 188 269 278 359 368 377 449 458 467 557 566

Can someone help me Convert Grammar to regular expresion

Can someone help me convert grammar to regular expression and explain how to do it on some complex grammars?
S -> aA | bB
A -> aC | bC | a | b
B -> aC | bC | a | b
C -> aA
This grammar of yours:
S -> aA | bB
A -> aC | bC | a | b
B -> aC | bC | a | b
C -> aA
Happens to be a right-regular grammar. As such, it describes a regular language and can easily be converted to a deterministic finite automaton:
q s q'
S a A
S b B
A a (C)
A b (C)
B a (C)
B b (C)
(C) a A
(C) b [D]
[D] a [D]
[D] b [D]
Here, S is the initial state, C is accepting and D is dead. To get a regular expression, treat this automaton as a NFA and start replacing symbol labels with regular expressions eliminating states:
S = aA + bB
A = aC + bC + a + b
B = aC + bC + a + b
C = aA + bD
D = aD + bD
Notice that D = aD + bD = (a + b)D is only true if D = {}. Rewriting:
S = aA + bB
A = aC + bC + a + b
B = aC + bC + a + b
C = aA
Now we can safely eliminate C by substitution:
S = aA + bB
A = aaA + baA + a + b = (aa + ba)A + (a + b)
B = aaA + baA + a + b = (aa + ba)A + (a + b)
Now we can use the rule Z = xZ + y => Z = x*y:
S = aA + bB
A = (aa + ba)*(a + b)
B = aaA + baA + a + b = (aa + ba)A + (a + b)
Now substitute:
S = aA + bB
A = (aa + ba)*(a + b)
B = (aa + ba)(aa + ba)*(a + b) + (a + b)
Now again:
S = a(aa + ba)*(a + b) + b((aa + ba)(aa + ba)*(a + b) + (a + b))
Now we can group like terms:
S = (a(aa + bb)* + b(aa + ba)(aa + ba)* + b)(a + b)
Notice that b(aa + ba)(aa + ba)* + b can be factored b((aa + ba)(aa + ba)* + e) and that (aa + ba)(aa + ba)* + e = (aa + ba)*:
S = (a(aa + bb)* + b(aa + ba)*)(a + b)
We can factor again:
S = (a + b)(aa + ba)*(a + b)
This last expression is a good, concise, correct regular expression for your language. It basically encodes the idea "see one symbol, then see another symbol, but if you see a third symbol it had better not be a b".

Adding to every other array position MS Access

I'm needing to take one array (firstArray) and input into a second array (secondArray). However, the first four fields are the same value. After the first four positions, it begins to alternate in values.
Example:
firstArray
+---------+
| ID# |
| Name |
| month1 |
| month2 |
| month3 |
| etc... |
+---------+
secondArray
+----------+
| ID# |
| Name |
| month1 |
| month2 |
| NewField |
| month3 |
| NewField |
| month4 |
| etc... |
+----------+
I'm fairly new to VBA, so I apologize for the awful code.
Code so far:
Dim i As Integer
i = 0
Dim j As Integer
ReDim secondArray(0 To (fieldCount - 4) * 2)
Dim finalCountDown As Integer
finalCountDown = (fieldCount - 4) * 2
secondArray(0) = firstArray(0)
secondArray(1) = firstArray(1)
secondArray(2) = firstArray(2)
secondArray(3) = firstArray(3)
i = 3
j = 3
Do Until i > finalCountDown
i = i + 1
secondArray(i) = "NewField"
i = i + 1
j = j + 1
secondArray(i) = firstArray(j)
Loop
I also have a MsgBox to iterate through and output my fields:
'//------ testing output
i = 0
For i = 0 To finalCountDown
MsgBox secondArray(i)
Next i
I appreciate any help! If there's any confusion, I'll gladly try to explain some more!
EDIT:
The two arrays are of different size but are dynamic. firstArray is firstly set to 20 positions while secondArray is originally set to 32 positions. (These are calculated each time this process is ran with the archived data being pulled. This allows my users to add data and not have to worry about having to manually add in the values to my arrays.)
EDIT2:
I've added Erik's portion to my code with a few alterations. I also added a separate counter for my firstArray in order to make sure it's inputting the correct rows into the correct positions of my secondArray.
EDIT3:
Here is the code that ended up working for me:
Dim i As Integer
i = 0
Dim j As Integer
'removed the " - 4"
ReDim secondArray(0 To (fieldCount * 2))
Dim finalCountDown As Integer
'removed the " - 4"
finalCountDown = (fieldCount * 2)
secondArray(0) = firstArray(0)
secondArray(1) = firstArray(1)
secondArray(2) = firstArray(2)
secondArray(3) = firstArray(3)
i = 3
'created own counter for firstArray
j = 3
Do Until i > finalCountDown
i = i + 1
secondArray(i) = "NewField"
i = i + 1
j = j + 1
secondArray(i) = firstArray(j)
Loop
The error I was getting was due "Subscript not in Range" due to the fact that my finalCountDown variable was less than my array needed to be. Allowing the variable to become larger than my array allowed my array to finish iterating through itself and now inputs the proper fields in the proper order.
I'm accepting Erik's answer as it was the stepping stone to answering the question!
For the adjusted code, you can do a simple check to check if the j value is valid:
Dim i As Integer
i = 0
Dim j As Integer
ReDim secondArray(0 To (fieldCount - 4) * 2)
Dim finalCountDown As Integer
finalCountDown = (fieldCount - 4) * 2
secondArray(0) = firstArray(0)
secondArray(1) = firstArray(1)
secondArray(2) = firstArray(2)
secondArray(3) = firstArray(3)
i = 3
j = 3
Do Until i > finalCountDown
i = i + 1
finalArray(i) = "NewField"
i = i + 1
j = j + 1
If j => LBound(colheaders) And j <= UBound(colHeaders) Then
finalArray(i) = colHeaders(j)
End If
Loop

Intercausal reasoning: Bayesian Network

Calculate P(Accident = 1 | Traffic = 1) and P(Accident = 1 | Traffic = 1, President = 1).
I have got an answer for P(Accident = 1 | Traffic = 1, President = 1) which is 0.15. But while applying the same scenarios for P(Accident = 1 | Traffic = 1), it does not seem to be working.
I tried P(A=1|T=1) ==> [ P(A=1) * P(T=1|A=1) ]/P(T=1) for P(Accident = 1 | Traffic = 1), but I am not getting the correct answer. I am not sure what and where I missed out.
Please explain the calculation for P(Accident = 1 | Traffic = 1)
Ilanman's setup is correct, but there's a slight mix up in his numbers that produces the wrong calculations.
P(T = 1) should actually equal 0.1449, and P(A = 1, T = 1) should equal 0.0504, and when divided together
0.0504/0.1449 = 0.3478
The error is made when the probabilities of P(Traffic = 1| President = 1, Accident = 0) and P(Traffic = 1| President = 0, Accident = 1) are mixed up.
So the final calculation for P(T = 1) should actually be,
=(0.9*0.01*0.1) + (0.6*0.01*0.9) + (0.5*0.99*0.1) + (0.1*0.99*0.9) = 0.1449
and the calculation for P(A = 1, T = 1) is
= (0.01*0.1*0.9) + (0.1*0.99*0.5) = 0.0504
Suppose we have a priori that a student George has a 30% chance of being intelligent. Now if we look at his grade in the class, we see the grade is low. Hence the probability of George being intelligent given the grade is low decreases.
P(i1|g3)=0.079
Now we went and checked the curriculum of the class and realized that the class was a difficult one. Hence the probability of George being intelligent given the grade is low and the class is difficult increases:
P(i1|g3,d1)=0.11
Now suppose Georges grade is B (g2). Hence the probability of George being intelligent given the grade as g2 increases
P(i1|g2)=0.175
Now if we consider that the class was tough too, the probability of George being intelligent given the grade as g2 and the class being tough increases
P(i1|g2,d1)=0.34
Hence in a way, we have explained away George's poor grade with the difficulty of the class. Explaining away is an instance of a general reasoning pattern called Intercausal Reasoning where causes of the same effect can interact. This intuition of providing an alternative explanation for the evidence can be made very precise.
Source: Daphne Koller course on Coursera
I recommend writing out the full joint distribution:
P(A,T,P) = P(P) * P(A) * P(T|P,A)
And use this to calculate whichever quantities you need. We want P(A = 1 | T = 1). Using conditional probability:
P(A = 1 | T = 1) = P(A = 1, T = 1) / P(T = 1)
P(T = 1)
= SUM_{over A, over P}
= P(A, P, T = 1)
= SUM_{over A, over P} P(P)*P(A)*P(T=1|P,A)
= P(T=1 | A=1, P=1)*P(A=1)*P(P=1)
+ P(T=1 | A=1, P=0)*P(A=1)*P(P=0)
+ P(T=1 | A=0, P=1)*P(A=0)*P(P=1)
+ P(T=1 | A=0, P=0)*P(A=0)*P(P=0)
= 0.9*0.01*0.1 + 0.6*0.1*0.99 + 0.5*0.9*0.01 + 0.1*0.99*0.9
= 0.1539
P(A = 1, T = 1)
= SUM_{over P} P(A=1, T=1, P)
= P(A=1, T=1, P=1) + P(A=1, T=1, P=0)
= P(A=1)*P(P=1)*P(T=1|A=1,P=1) + P(A=1)*P(P=0)*P(T=1|A=1,P=0)
= 0.01*0.1*0.9 + 0.1*0.99*0.6
= 0.0603
Therefore:
P(A = 1 | T = 1) = P(A = 1, T = 1) / P(T = 1)
= 0.0603 / 0.1539
= 0.3918
For calculating P(Accident = 1 | Traffic = 1), you should follow this procedure.
P(A = 1 | T = 1) = P(A = 1, T = 1) / P(T = 1)
So first we need to calculate P(A = 1, T = 1), that is:
P (A = 1, T = 1) = P(T=1 , A=1 , P=0) + P(T=1, A=1, P=1 )
Then we have:
P(T=1, A=1 , p=0) = P(T=1 | A=1, p=0) p(A=1) p(p=0) = 0.5 * 0.1 * 0.99 = 0.0495
Following the same method you can calculate P(T=1, A=1, p=1) that would lead to 0.0009.
So:
P (A = 1, T = 1) = P(T=1 , A=1 , P=0) + P(T=1, A=1, P=1 ) = 0.0495 + 0.0009 = 0.0504
=>
P(A = 1 | T = 1) = 0.0504 / P(T = 1)
For calculating P(T=1), you should follow the same manner. So
P(T=1) = P(T=1,p=0, A=0) + P(T=1, p=0, A=1) + P(T=1, p=1, A=0) + P(T=1, p=1, A=1)
Then
P(T=1, p=0, A=0 ) = P(T=1 | p=0, A=0 ) * P(p=0) * P(A=0)
and so on...

Conditional ELSEIF does not work

Not sure how to solve this. "a" was meant to start from 1 to NumData, but I have deliberately change the start from 44200 to check the ELSEIF. For NumData = 117,350,
I would expect the 3rd ELSEIF to be activated. Instead throughout the whole run, it only step-into the first ELSEIF even though the "a" value does not meet the conditions.
What should I do?
For a = 44200 To NumData 'Int1
If a > 1 Then
If UCase(Trim(Range1(a, 3))) = UCase(Trim(Range1(a - 1, 3))) Then
GoTo Line1 'Next count loop if next Platform name the same
End If
End If
For b = 1 To NumData
lat1 = Range1(a, 5)
lat2 = Range1(b, 5)
long1 = Range1(a, 6)
long2 = Range1(b, 6)
CompRad = Dist(lat1, lat2, long1, long2)
If (CompRad <= Radius And CompRad >= 0) Then
z = CLng(NumData / 8)
If a <= CLng(NumData / 8) Then
For c = 1 To 6
Range2(d, c) = Range1(b, c)
Next c
Acc_Sum2 = Acc_Sum2 + Range2(d, 4)
d = d + 1
ElseIf CLng(NumData / 8) < a <= 2 * CLng(NumData / 8) Then
z = 2 * CLng(NumData / 8)
For c = 1 To 6
Range3(e, c) = Range1(b, c)
Next c
Acc_Sum3 = Acc_Sum3 + Range3(e, 4)
e = e + 1
ElseIf 2 * CLng(NumData / 8) < a <= 3 * CLng(NumData / 8) Then
For c = 1 To 6
Range4(f, c) = Range1(b, c)
Next c
Acc_Sum4 = Acc_Sum4 + Range4(f, 4)
f = f + 1
ElseIf 3 * CLng(NumData / 8) < a <= 4 * CLng(NumData / 8) Then
z = 3 * CLng(NumData / 8)
For c = 1 To 6
Range5(g, c) = Range1(b, c)
Next c
Acc_Sum5 = Acc_Sum5 + Range5(g, 4)
g = g + 1
ElseIf 4 * CLng(NumData / 8) < a <= 5 * CLng(NumData / 8) Then
For c = 1 To 6
Range6(h, c) = Range1(b, c)
Next c
Acc_Sum6 = Acc_Sum6 + Range6(h, 4)
h = h + 1
ElseIf 5 * CLng(NumData / 8) < a <= 6 * CLng(NumData / 8) Then
For c = 1 To 6
Range7(i, c) = Range1(b, c)
Next c
Acc_Sum7 = Acc_Sum7 + Range7(i, 4)
i = i + 1
ElseIf 6 * CLng(NumData / 8) < a <= 7 * CLng(NumData / 8) Then
For c = 1 To 6
Range8(j, c) = Range1(b, c)
Next c
Acc_Sum8 = Acc_Sum8 + Range8(j, 4)
j = j + 1
ElseIf 7 * CLng(NumData / 8) < a <= NumData Then
For c = 1 To 6
Range9(k, c) = Range1(b, c)
Next c
Acc_Sum9 = Acc_Sum9 + Range9(k, 4)
k = k + 1
End If
End If
Next b
Line1:
Next a
Your conditions like:
1 < a <= 10
are always true. First part (1 < a) evaluates to True or False and then it is converted to integer (True = 1, False = 0). Both values are <=10.
You should change thes conditions to:
(1 < a) And (a <= 10)
Brackets are optional, comparison operators have higher precedence.
user3964075 nailed the core issue. I think making the code a little bit more readable will help to filter out other possible trouble areas. Why do you set the value of 'z' and then not use it?
z = CLng(NumData / 8)
Where are the variables d, e, f...; Range2, Range3, Range4...; Acc_Sum2, Acc_Sum3... assigned, and what are they doing? Can each group be replaced by a single variable?
You may also want to create a simple Between function
to clean up a lot of your conditional statements.
Public Function Between(x As Integer, min As Integer, max As Integer) As Boolean
Between = x <= max And x >= min
End Function
Thanks, user3964075 & Carl for your prompt response. It's worked! Carl, the z variable was slotted in when I was trying to figure out the problem. I thought it would be too much to post the whole code. It does require a lot of cleaning up. Appreciate your tips.