Finding ones in an array with J - arrays

I will explain my problem in plain English and then show my attempts in J.
Sum the indices of the 1's of a list of 1's and 0's and see if they equal another number.
e.g. given 1 0 1 1 0
the indices are 0,2, and 3, and their sum is 5. So I can then test to see if it quals another number (obviously only true for 5 in this case).
Here's my J:
indexsumtest =: =+/I.
v =: 1 0 1 1 0
5 indexsumtest v
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
What the? Here I assumed indexsumtest was a dyadic verb, maybe I need to explicitly put in x and y?
indexsumtest =: x =+/I. y
5 indexsumtest v
|value error: x
| 5 indexsumtest v
Nope. That made things worse.
So I start from the beginning:
I. v
0 2 3
Correct!
+/I. v
5
Correct again.
5 =+/I. v
1
1 means true. SO I did something right.
Why can't I compact these three operations into a single verb?

It is one that bites everyone now and then and it results because
5 =+/I. v
actually has I. acting on v, then the result is acted on by +/, then that result is tested against 5 using the = comparison. So when we define
indexsumtest =: =+/I.
we get
5 indexsumtest v
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
because indexsumtest has been defined as a tacit verb which processes its arguments as a fork as MPelletier suggested. In other words you actually don't get =+/I. in place of indexsumtest you get (=+/I.) which is a 3 verb fork where the first and third verbs take both arguments and the result of each is sent to the +/ in the centre.
MPelletier also suggests that a tacit form that does what you wanted is
[ = [: +/ [: I. ]
which will work and is actually created by J if you change your definition to 13
indexsumtest =: 13 : 'x =+/I. y'
indexsumtest
[ = [: +/ [: I. ]
Yep, that is right J will actually do most tacit conversions for you if you use the 13 : conjunction to define. Pretty cool, eh? Only problem is that it does not use hooks in this automatic generation, which can simplify the code. A hook is a two verb combination that has the right verb work on the right argument and the result is used as the right argument to the left verb which uses the left argument in the dyadic case (or the original right argument in the monadic case).
When x and y are left and right arguments and u and v are the first and second verbs then
x ( u v) y becomes x u (v y)
or in monadic case
( u v) y becomes y u (v y)
If you are still with me (good for you!) this means that we can use a hook to simplify the tacit if we set u to = and v to +/#I. (the # is a conjunction that joins +/ and I. and makes them work as one verb). So finally
indexsumtacit =: = +/#I.
5 indexsumtacit v
1
As mindbending as J is when you start, it is really neat when you understand the rules that it plays by and then start to get them to do your bidding. Hope this helps.

Consider the classic mean function:
mean =: +/%#
mean i.6
3 part declarations like that operate this way:
# is performed against y
+/ is performed against y
% is performed dyadically against the results of +/ and # in their respective places
The principle is the same with your dyadic function:
I. is performed against x and y
= is performed against x and y
+/ is performed against the results of = and I. in their respective places
So, doing
indexsumtest =: =+/I.
5 indexsumtest 1 0 1 1 0
Is equivalent to
(5 = 1 0 1 1 0) +/ (5 I. 1 0 1 1 0)
Far from what you want.
The simple trick is to define a dyadic function explicitly:
indexsumtest =: 4 : 'x =+/I. y'
J's tacit definition also suggests this:
[ = [: +/ [: I. ]
Which is a bit heavy for my taste.

It is all about how J parses an expression. When J sees a verb, it implicitly adds a parentheses around it. So 5 indexsumtest v is 5 (=+/I.) v; while 5 =+/I. v is actually 5 =+/ (I. v). These two are different as answers above.
I found that it is extremely helpful to understand how J evaluates expressions by reading Appendix 1 of Learning J. This deserves a whole chapter rather than an appendix for any J tutorials.

Related

How can I create a new matrix that from the other's elements?

I want to pick out the elements which are
(2*pi*k),
where k=0,1,2,3... which means integer, and fill them (i1) into the other matrix.
But my problem is, I don't know how to make "k" be row. (By the way, dividends and divisors are float, so I need to find the approximations and see them as 2*pi*k).
My code, only can find the elements which are (2*pi*k), but can't order them like if k=1, then it will be put into k=1 row; if k=2, then the element should be put into k=2 row.
For example,
A = [2*pi 6 3 4;0.5*pi 0 2;3.1 7 4 8;2*pi 7 2 9;2.6 4*pi 6*pi 0]
I want the output to be
B = [0 2*pi 4*pi 6*pi;0 2*pi NaN NaN;NaN 2*pi NaN NaN]
This is my code:
k=0;
for m=380:650;
for n=277:600;
if abs((rem(abs(i(m,n)),(2*PI)))-(PI))>=3.11;
k=k+1;
B(m,k)=i1(m,n);
end
end
k=0;
end
It can find what I want but they seem not to be ordered the way I want.
As others, I'm a bit unsure what you want. Here's how I understood it and would code it:
check whether (2*pi*k) is contained in A, you want a numerical approach
output binary result
here's the code:
testPI=#(k) (2*pi*k); %generates 2*pi*k, where k is up to the user
A = [2*pi 6 3 4;0.5*pi 0 2 0;3.1 7 4 8;2*pi 7 2 9;2.6 4*pi 6*pi 0]; %A from example (fixed dimension error)
ismember(A,f(1:10)) %test if k=1:10 is contained in A
ans =
5×4 logical array
1 0 0 0
0 0 0 0
0 0 0 0
1 0 0 0
0 1 1 0
Adapt 1:10 to any value you'd like. Of course this only works if k is within reasonable range, otherwise this approach is suboptimal

How are the individual bits accessed in this code?

So I saw this code which printed out individual bits of any number.I do not understand why the individual bits are accessed and not the entire number itself
#include <stdio.h>
int main()
{
int x=10, b;
for(b=0; x!=0; x>>=1) {
printf("%d:%d\n", b, (x&1));
b++;
}
}
OUTPUT:
0:0
1:1
2:0
3:1
Please help me understand this piece of code.
In your code you are printing the value of X variable in binary. For this, your code, use logical operation as AND operator and right-shift.
In the loop condition, you displace the X variable one bit to the right.
for b = 0 you get x = 1010
for b = 1 you get x = 101
for b = 2 you get x = 10
for b = 3 you get x = 1
Then, in your print, show your loop iterator (b) and your X variable AND 1.
The AND operator get this values:
0 AND 0 = 0
0 AND 1 = 0
1 AND 0 = 0
1 AND 1 = 1
In your case, you have:
1010 AND (000)1 = 0
101 AND (00)1 = 1
10 AND (0)1 = 0
1 AND 1 = 1
There are two questions in your post: how to access an individual bit ? and how to select that bit ?
Concerning the first question, suppose you want to access the less significant bit (or, to make it simpler, the rightmmost bit), you can use a mask: suppose your data is b0011 for instance, you can mask with b0001 (i.e. 1 in decimal).
0 0 1 1
& 0 0 0 1
---------
0 0 0 1
The & operator is the bitwise and. If you look in your code sample, you have printf("%d:%d\n", b, (x&1)); in which you can see x & 1, i.e. print the rightmost bit of x.
Now comes the second question: how to put each bit in the rightmost position one after each other (said otherwise, how to select the bit to print) ? An easy solution is to shift your data of 1 position to the right each time you want to select the next bit (i.e. the bit to the left of the current one).
In C, you can shift using >>. For instance, if x is b0011, then x >> 1 is b0001 (in this case, you fill the leftmost position with zeros, but in some cases it might be trickier). If you look in you code sample, you have x>>=1 in the for-loop, which assigns x >> 1 in x.
Hence, suppose you take the previous example:
0 0 1 1 = x 0 0 0 1 = x
& 0 0 0 1 & 0 0 0 1
--------- x >> 1 = b0001 -> x ---------
0 0 0 1 0 0 0 1
and so one...
A last bonus point, the loop stopping condition is x != 0, this implies that you don't prints all bits of your data, but only the bits up to the leftmost 1 (included). For instance, in the above example, after printing the two rightmost bits, x becomes 0 and the loop exits.

Inserting an element into an array in J

What is the best practice for inserting an element into an array at an arbitrary position in J?
I guess this is sort of a double question: my main issue is figuring out how to provide three arguments to the verb I want to create. The gist of the code that I want to write is
insert =. dyad : '(n {. y) , x , (n }. y)'
for a position n. The best solution to this that I can think of is taking a two-length array of boxes as the right argument and the position as the left, but that seems a bit clunky
insert =. dyad : 0
NB. the array to be inserted is the first argument
i =. > {. y
NB. the original array is the second argument
a =. > {: y
(x {. a) , i , (x }. a)
)
EDIT: Furthermore, would it be possible to take an array of indices to insert the item at and an array of items to be inserted at those indices -- i.e. inserting multiple items at a time? It seems to me like this is something J would be good at, but I'm not sure how it would be done.
Boxing the arguments is an often used technique. You can use multiple assignment for cleaner code:
f =: 3 : 0
'arg1 arg2' =: y
)
f (i.5);(i.9) NB. arg1 is i.5, arg2 is i.9
To insert array a at position n in L, you can more compactly write:
n ({., a, }.) L
Another way to insert an element into an array is to fill with #!.. Some examples:
1 1 1j2 1 (#!.999) 1 2 3 4
1 2 3 999 999 4
1j1 1 1j1 1 (#!.999) 1 2 3 4
1 999 2 3 999 4
1 1 0j1 1 (#!.999) 1 2 3 4
1 2 999 4
Depending on your needs, there are many other tricks you can use, like shifting by n n |. and then undoing the shift with dual &.:
a,&. (n |. ]) L
(reply to the comment that got too long)
Both from readability and performance standpoint the two methods are about the same. I would slightly favor the first as more readable but would probably use the second.
You can use timespacex verb to check the performance: eg.
NB. define the different methods
f1 =: 4 :'x ({., a, }.) y
f2 =: 4 :' a,&. (x |. ]) y'
NB. set some parameters
a =: 1000 $ 9
L =: 1e6 $ 5
n =: 333456
NB. check if the too methods give identical results
(n f1 L) -: (n f2 L)
1
NB. iterate 100 times to get performance averages
100 timespacex'n f1 L'
0.00775349 2.09733e7
100 timespacex'n f2 L'
0.00796431 1.67886e7

How can I store a part of an array to another array in matlab?

I am trying to write a svm code, but i am literally a beginner in matlab.
So in my code, in a for loop, i should store predictions. The data is like this:
testIdx = [1 1 1 0 0 0 0 0 1 0 1 1]'; % i wrote it like this but it says logical
and
pred = [1 1 1 0 1 0]'; % again logical
So i want to form a 12 length array and turn its 1st,2nd,3rd,9th,11th,12th elements into 1 1 1 0 1 0, and likewise rest of test elements into another set of 0/1s in other iteration.
If possible let it be a normal array, not logical. Thanks in advance
I did it myself old style but there must be a shorter direct way right?
Y = zeros ( size(testIdx,1), 1) ;
a=1;
for i = 1:size(testIdx,1)
if testIdx(i) ==1
Y(i) = pred(a);
a=a+1;
end
end
If you create testIdx and pred the way you specified, then they are double and not logical type. To use logical indexing, it is easiest if testIdx is converted to the logical type. Then you can simply use
testIdx = [1 1 1 0 0 0 0 0 1 0 1 1]';
pred = [1 1 1 0 1 0]';
Y = zeros(size(testIdx));
Y(logical(testIdx)) = pred;
With Y(logical(testIdx), you select all indexes which are set to 1 in the testIdx vector and then write predto these indexes.

How do I use argument twice in a function in J?

I want to write prime function for purposes of learning J.
So far I've come up with this:
=&0+/(=&0)(2+i.(-&2)y)|y
It's working great except that I should store number in y variable.
y=.5
=&0+/(=&0)(2+i.(-&2)y)|y NB. prime cheker
1
y=.13
=&0+/(=&0)(2+i.(-&2)y)|y NB. prime cheker
1
y=.14
=&0+/(=&0)(2+i.(-&2)y)|y NB. prime cheker
0
How do I write a function that works what takes argument? i.e. f 13 -> 1
You can just define a verb using : 3.
f =: 3 :'=&0+/(=&0)(2+i.(-&2)y)|y'
f 5
1
f 13
1
f 10
0
When using : 3, y always refers to the right hand argument of the verb.
If you want to define a dyadic verb, use : 4 and x for the left argument.
Btw, you can set the value of a variable anywhere:
=&0+/(=&0)(2+i.(-&2)y)|y=.5
1
=&0+/(=&0)(2+i.(-&2)y)|y=.10
0
You might find the Defining Verbs Guide on the J Wiki useful.
As has already been mentioned you can take your sentence and define it as a verb using the following syntax:
isPrime0=: 3 : '=&0+/(=&0)(2+i.(-&2)y)|y'
However it is probably more natural to write it like this:
isPrime1=: 3 : '0 = (+/ 0 = (2 + i. y - 2) | y)'
You could also define a tacit version (doesn't refer to the arguments) like any of the following:
isPrime2=: 0 = [: +/ 0 = ] |~ 2 + [: i. 2 -~ ]
isPrime3=: 0 = [: +/ 0 = ] |~ 2 + i.#:-&2 NB. replace train with verb composed using conjunctions
isPrime4=: 0 = [: +/ 0 = ] |~ i.&.(-&2) NB. use Under to re-add the 2 after Integers
isPrime5=: 0 -.#e. i.&.(-&2) | ] NB. check no zero in result

Resources