I was experimenting with generating truth tables in J:
nand =: *:
nand /~ 0 1
1 1
1 0
bxor =: 22 b. NB. Built-in bitwise XOR
bxor /~ 0 1
0 1
1 0
Now I want to define my own logical xor, which I did like so:
xor =: 3 : 0
]y NB. monadic case is just the identity
:
(x*.-.y)+.(y*.-.x) NB. dyadic case is (x AND NOT y) OR (y AND NOT x)
)
This works as I expect when I call it directly.
0 xor 0 1
0 1
1 xor 0 1
1 0
But it doesn't generate a truth table:
xor /~ 0 1
0 0
Why not?
I thought maybe the problem was that ]/~ 0 1 itself produced a 1 x 2 array, so I changed the monadic part to use nand (*:y) because it produces the 2x2 array:
*:/~ 0 1
1 1
1 0
xor =: 3 : 0
*:y NB. certainly wrong, but at least has 2x2 shape.
:
(x*.-.y)+.(y*.-.x)
)
But I still get the same behavior:
xor /~ 0 1
0 0
Can someone help me understand the flaw in my thinking?
Your xor has infinite rank, while *:,~: have rank 0. You can verify that by using b.: v b. 0 like so:
~: b. 0
_ 0 0
*: b. 0
0 0 0
xor b. 0
_ _ _
What this means is that xor operates on the list 0 1 rather than on each individual atom 0, 1.
You will get the result you expect if you use xor with rank 0:
xor"0 /~ 0 1
0 1
1 0
Or if you define xor to be of rank 0.
Related
I am debugging some VBA code and I have an IIF function which I don't understand what is doing. It's IIF(constant And i, "TRUE", "FALSE"), where I gets values from 0 to n.
I know that this function is equivalent to IF in Excel. But in this case what is the condition? What does the expression number and number means? I run this sample:
Sub Sample()
For i = 0 To 20
Cells(i + 1, 1) = i
Cells(i + 1, 2) = 4 And i
Next i
End Sub
And I get the values below:
The expression 4 And i will do an arithmetic AND-operation. Example:
6: 0 0 0 0 0 1 1 0
4: 0 0 0 0 0 1 0 0
Result: 0 0 0 0 0 1 0 0
11: 0 0 0 0 1 0 1 1
4: 0 0 0 0 0 1 0 0
Result: 0 0 0 0 0 0 0 0
So 6 AND 4 is 4 while 11 AND 4 is 0.
Now 0 is seen as False and everything not 0 is seen as True. Used in an IIF-statement, all numbers that have the 3rd bit (counting from right) set will execute the True-part of the IIF, all others the False.
Your And operator does a bit wise comparison:
result = expression1 And expression2
When applied to numeric values, the And operator performs a bitwise comparison of identically positioned bits in two numeric expressions and sets the corresponding bit in result according to the following table.
If bit in expression1 is
And bit in expression2 is
The bit in result is
1
1
1
1
0
0
0
1
0
0
0
0
Since the logical and bitwise operators have a lower precedence than other arithmetic and relational operators, any bitwise operations should be enclosed in parentheses to ensure accurate results.
So converting the 4 into binary it results in 100. I have done that in the 3ʳᵈ column below, where I converted all numbers of the 1ˢᵗ column to binaries. The other 2 columns are just filled up with zeros for better visibility:
So watching the table above you only get a 1 as result if both bits in the same position are a 1 otherwise you get a 0. That means you always get a 4 as result if 4 and i has a 1 in the 3ʳᵈ bit from the right due to the bitwise comparison (see the red bits).
In information theory, multivariate mutual information (MMI) could be synergy (negative) or redundancy (positive). To simulate this two cases, assuming three variables X, Y and Z, all of them takes 0 or 1 (binary variable). And we repeat sampling them 12 times.
Case 1:
X = [ 0 0 0 0 0 0 1 1 1 1 1 1 ]
Y = [ 0 0 0 0 1 1 0 0 1 1 1 1 ]
Z = [ 0 0 1 1 1 1 0 0 0 0 1 1 ]
In this case, we assume a mechanism among XYZ taht when both Y and Z are 0 or 1, X takes 0 or 1 respectively. When Y = 0, Z = 1, then X takes 0, and Y = 1, Z = 0, then X takes 1.
The mmi(X,Y,Z) = -0.1699 in this case, indicating a synergy effect among three variable.
Case 2:
X = [ 0 0 0 0 0 0 1 1 1 1 1 1 ]
Y = [ 0 0 0 0 0 1 0 1 1 1 1 1 ]
Z = [ 0 1 1 1 1 1 0 0 0 0 0 1 ]
the machanism in this case is same as above. The difference is there are more samples of XY takes different value and less samples of both XY are 0 or 1.
The mmi(X,Y,Z) = 0.0333, indicating a redundancy.
So far, can I say in these two cases, synergy and redundancy show the similar mechanism (or relationship) among three variables? But how do we understand redundancy and particularly synergy in realistic data?
I'm dabbling my feet with J and, to get the ball rolling, decided to write a function that:
gets integer N;
spits out a table that follows this pattern:
(example for N = 4)
1
0 1
0 0 1
0 0 0 1
i.e. in each row number of zeroes increases from 0 up to N - 1.
However, being newbie, I'm stuck. My current labored (and incorrect) solution for N = 4 case looks like:
(4 # ,: 0 1) #~/"1 1 (1 ,.~/ i.4)
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
And the problem with it is twofold:
it's not general enough and looks kinda ugly (parens and " usage);
trailing zeroes - as I understand, all arrays in J are homogeneous, so in my case every row should be boxed.
Like that:
┌───────┐
│1 │
├───────┤
│0 1 │
├───────┤
│0 0 1 │
├───────┤
│0 0 0 1│
└───────┘
Or I should use strings (e.g. '0 0 1') which will be padded with spaces instead of zeroes.
So, what I'm kindly asking here is:
please provide an idiomatic J solution for this task with explanation;
criticize my attempt and point out how it could be finished.
Thanks in advance!
Like so many challenges in J, sometimes it is better to keep your focus on your result and find a different way to get there. In this case, what your initial approach is doing is creating an identity matrix. I would use
=/~#:i. 4
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
You have correctly identified the issue with the trailing 0's and the fact that J will pad out with 0's to avoid ragged arrays. Boxing avoids this padding since each row is self contained.
So create your lists first. I would use overtake to get the extra 0's
4{.1
1 0 0 0
The next line uses 1: to return 1 as a verb and boxes the overtakes from 1 to 4
(>:#:i. <#:{."0 1:) 4
+-+---+-----+-------+
|1|1 0|1 0 0|1 0 0 0|
+-+---+-----+-------+
Since we want this as reversed and then made into strings, we add ":#:|.#: to the process.
(>:#:i. <#:":#:|.#:{."0 1:) 4
+-+---+-----+-------+
|1|0 1|0 0 1|0 0 0 1|
+-+---+-----+-------+
Then we unbox
>#:(>:#:i. <#:":#:|.#:{."0 1:) 4
1
0 1
0 0 1
0 0 0 1
I am not sure this is the way everyone would solve the problem, but it works.
An alternative solution that does not use boxing and uses the dyadic j. (Complex) and the fact that
1j4 # 1
1 0 0 0 0
(1 j. 4) # 1
1 0 0 0 0
(1 #~ 1 j. ]) 4
1 0 0 0 0
So, I create a list for each integer in i. 4, then reverse them and make them into strings. Since they are now strings, the extra padding is done with blanks.
(1 ":#:|.#:#~ 1 j. ])"0#:i. 4
1
0 1
0 0 1
0 0 0 1
Taking this step by step as to hopefully explain a little better.
i.4
0 1 2 3
Which is then applied to (1 ":#:|.#:#~ 1 j. ]) an atom at a time, hence the use of "0
Breaking down what is going on within the parenthesis. I first take the right three verbs which form a fork.
( 1 j. ])"0#:i.4
1 1j1 1j2 1j3
Now, effectively that gives me
1 ":#:|.#:#~ 1 1j1 1j2 1j3
The middle tine of the fork becomes the verb acting on the two noun arguments.The ~ swaps the arguments. so it becomes equivalent to
1 1j1 1j2 1j3 ":#:|.#:# 1
which because of the way #: works is the same as
": |. 1 1j1 1j2 1j3 # 1
I haven't shown the results of these components because using the "0 on the fork changes how the arguments that are sent to the middle tine and assembled later. I'm hoping that there is enough here that with some hand waving the explanation may suffice
The jump from tacit to explicit can be a big one, so it may be a better exercise to write the same verb explicitly to see if it makes more sense.
lowerTriangle =: 3 : 0
rightArg=. i. y
complexCopy=. 1 j. rightArg
1 (":#:|.#:#~)"0 complexCopy
)
lowerTriangle 4
1
0 1
0 0 1
0 0 0 1
lowerTriangle 5
1
0 1
0 0 1
0 0 0 1
0 0 0 0 1
See what happens when you 'get the ball rolling'? I guess the thing about J is that the ball goes down a pretty steep slope no matter where you begin. Exciting, eh?
Let's suppose I have a six by six cube each with xyz coordinates.
Moving from the middle cube (0,0,0) to the other sides (let's say (0,1,0), I would like to find the other 4 components that are peperdicular to the middle cube following the direction of (0,1,0).
If we move one dimension, this is easy (and my brain can grasp it)... the components will be (-1,0,0),(+1,0,0), (0,0,+1), (0,0,-1).
Now, could somebody help me with moving to size where two (to (1,1,0) or three coordinates change (1,1,-1)?
Thanks,
Rodrigo
There is infinity number of perpendicular vectors in 3D space.
If you want to restrict their components by values 0, +-1, then consider the next approach:
Your vector components are A=(ax, ay, az). Dot product of perpendicular vector B=(bx, by, bz) with A must be zero
ax * bx + ay * by + az * bz = 0
To form components of B:
get A components
nullify arbitrary component (if one of other components is not zero)
exchange two another components
negating one of them
example:
(bx, by, bz) = (0, -az, ay)
So for vector A=(1,1,-1) one of six perpendiculars is B1=(0, 1, 1)
For vector A=(1,1,0) there are four variants with given restrictions:
(-1, 1, 0)
(1, -1, 0)
(0, 0, 1)
(0, 0, -1)
If you want to fix a pair components of perp. vector - just substitute needed values in dot product formula and solve for unknown component of B
Thank you, this is exactly what I did.
Here is my solution:
(in matlab) I created a number of all possibility unit values:
pos_vals=[ 0 0 0 ; -1 0 0 ; 1 0 0 ; 0 1 0 ; 0 -1 0 ; -1 -1 0 ; 1 1 0 ; -1 1 0 ; 1 -1 0; 0 0 1 ; -1 0 1 ; 1 0 1 ; 0 1 1 ; 0 -1 1 ; -1 -1 1 ; 1 1 1 ; -1 1 1 ; 1 -1 1 ; 0 0 -1 ; -1 0 -1 ; 1 0 -1 ; 0 1 -1 ; 0 -1 -1 ; -1 -1 -1 ; 1 1 -1 ; -1 1 -1 ; 1 -1 -1];
And then based on my reference coordinate [eg vec_ofinterest=(1,1,0) ] ,
I do the following:
for idx_posvals=1:size(pos_vals,1)
gg(idx_posvals)=dot(vec_ofinterest,pos_vals(idx_posvals,:));
if gg(idx_posvals) == 0
pos_vals(idx_posvals,:)
end
end
Which give me 8 solutions (including the reciprocals you mentioned).
-1 1 0
1 -1 0
0 0 1
-1 1 1
1 -1 1
0 0 -1
-1 1 -1
1 -1 -1
It looks like this is solved. In case somebody find and error, please let me know.
Rodrigo
Assume I have two lists, one is the text t, one is a list of characters c. I want to count how many times each character appears in the text.
This can be done easily with the following APL code.
+⌿t∘.=c
However it is slow. It take the outer product, then sum each column.
It is a O(nm) algorithm where n and m are the size of t and c.
Of course I can write a procedural program in APL that read t character by character and solve this problem in O(n+m) (assume perfect hashing).
Are there ways to do this faster in APL without loops(or conditional)? I also accept solutions in J.
Edit:
Practically speaking, I'm doing this where the text is much shorter than the list of characters(the characters are non-ascii). I'm considering where text have length of 20 and character list have length in the thousands.
There is a simple optimization given n is smaller than m.
w ← (∪t)∩c
f ← +⌿t∘.=w
r ← (⍴c)⍴0
r[c⍳w] ← f
r
w contains only the characters in t, therefore the table size only depend on t and not c. This algorithm runs in O(n^2+m log m). Where m log m is the time for doing the intersection operation.
However, a sub-quadratic algorithm is still preferred just in case someone gave a huge text file.
NB. Using "key" (/.) adverb w/tally (#) verb counts
#/.~ 'abdaaa'
4 1 1
NB. the items counted are the nub of the string.
~. 'abdaaa'
abd
NB. So, if we count the target along with the string
#/.~ 'abc','abdaaa'
5 2 1 1
NB. We get an extra one for each of the target items.
countKey2=: 4 : '<:(#x){.#/.~ x,y'
NB. This subtracts 1 (<:) from each count of the xs.
6!:2 '''1'' countKey2 10000000$''1234567890'''
0.0451088
6!:2 '''1'' countKey2 1e7$''1234567890'''
0.0441849
6!:2 '''1'' countKey2 1e8$''1234567890'''
0.466857
NB. A tacit version
countKey=. [: <: ([: # [) {. [: #/.~ ,
NB. appears to be a little faster at first
6!:2 '''1'' countKey 1e8$''1234567890'''
0.432938
NB. But repeating the timing 10 times shows they are the same.
(10) 6!:2 '''1'' countKey 1e8$''1234567890'''
0.43914
(10) 6!:2 '''1'' countKey2 1e8$''1234567890'''
0.43964
Dyalog v14 introduced the key operator (⌸):
{⍺,⍴⍵}⌸'abcracadabra'
a 5
b 2
c 2
r 2
d 1
The operand function takes a letter as ⍺ and the occurrences of that letter (vector of indices) as ⍵.
I think this example, written in J, fits your request. The character list is longer than the text (but both are kept short for convenience during development.) I have not examined timing but my intuition is that it will be fast. The tallying is done only with reference to characters that actually occur in the text, and the long character set is looked across only to correlate characters that occur in the text.
c=: 80{.43}.a.
t=: 'some {text} to examine'
RawIndicies=: c i. ~.t
Mask=: RawIndicies ~: #c
Indicies=: Mask # RawIndicies
Tallies=: Mask # #/.~ t
Result=: Tallies Indicies} (#c)$0
4 20 $ Result
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 4 0
0 0 1 0 0 0 2 1 2 0 0 0 1 3 0 0 0 2 0 0
4 20 $ c
+,-./0123456789:;<=>
?#ABCDEFGHIJKLMNOPQR
STUVWXYZ[\]^_`abcdef
ghijklmnopqrstuvwxyz
As noted in other answers, the key operator does this directly. However the classic APL way of solving this problem is still worth knowing.
The classic solution is "sort, shift, and compare":
c←'missippi'
t←'abcdefghijklmnopqrstuvwxyz'
g←⍋c
g
1 4 7 0 5 6 2 3
s←c[g]
s
iiimppss
b←s≠¯1⌽s
b
1 0 0 1 1 0 1 0
n←b/⍳⍴b
n
0 3 4 6
k←(1↓n,⍴b)-n
k
3 1 2 2
u←b/s
u
imps
And for the final answer:
z←(⍴t)⍴0
z
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
z[t⍳u]←k
z
0 0 0 0 0 0 0 0 3 0 0 0 1 0 0 2 0 0 2 0 0 0 0 0 0 0
This code is off the top of my head, not ready for production. Have to look for empty cases - the boolean shift is probably not right for all cases....
"Brute force" in J:
count =: (i.~~.) ({,&0) (]+/"1#:=)
Usage:
'abc' count 'abdaaa'
4 1 0
Not sure how it's implemented internally, but here are the timings for different input sizes:
6!:2 '''abcdefg'' count 100000$''abdaaaerbfqeiurbouebjkvwek''' NB: run time for #t = 100000
0.00803909
6!:2 '''abcdefg'' count 1000000$''abdaaaerbfqeiurbouebjkvwek'''
0.0845451
6!:2 '''abcdefg'' count 10000000$''abdaaaerbfqeiurbouebjkvwek''' NB: and for #t = 10^7
0.862423
We don't filter input date prior to 'self-classify' so:
6!:2 '''1'' count 10000000$''1'''
0.244975
6!:2 '''1'' count 10000000$''1234567890'''
0.673034
6!:2 '''1234567890'' count 10000000$''1234567890'''
0.673864
My implementation in APL (NARS2000):
(∪w),[0.5]∪⍦w←t∩c
Example:
c←'abcdefg'
t←'abdaaaerbfqeiurbouebjkvwek'
(∪w),[0.5]∪⍦w←t∩c
a b d e f
4 4 1 4 1
Note: showing only those characters in c that exist in t
My initial thought was that this was a case for the Find operator:
T←'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
C←'MISSISSIPPI'
X←+/¨T⍷¨⊂C
The used characters are:
(×X)/T
IMPS
Their respective frequencies are:
X~0
4 1 2 4
I've only run toy cases so I have no idea what the performance is, but my intuition tells me it should be cheaper that the outer product.
Any thoughts?