Adverbs
- used generally to apply a function over a list
each
'
- used to apply a function to each individual element of a list
q) //function to count number of divisors of a number q) divisors:{count where 0=x mod 1+til x} q) //works fine with atomic values q)divisors 5 2 q)divisors 10 4 q)divisors 20 6 q) //doesn't work with list q)l 12 10 1 90 73 90 43 90 84 63 93 54 38 97 88 58 68 45 2 39 q)divisors l 'type [2] (.q.til) [1] divisors:{count where 0=x mod 1+til x} q) //we use each to execute divisors function over each element of list q)divisors each l 6 4 1 12 2 12 2 12 12 6 4 8 4 2 8 4 6 6 2 4
- also used for nested lists
each-both ,'
- it is polyadic form of
each
- often used for applying diadic function element wise to a pair of lists
- each-both can also be applied to higher valency functions
each-right /:
- used with diadic function where we want to use a list as right-hand argument
- join each right hand arguments to left hand argument
- iterate over right
each-left \:
- used with diadic function where we want to use a list as right-hand argument
- join each left hand argument to right hand argument
- iterate over left
- many inbuilt operator already works on list and atom in same manner - thus if we get desired result with such operators we shouldn't be using adverbs with them
each-prior ':
- used to apply a diadic function to a list element and its predecessor in the list
- can also be used to show each element of list alongside its predecessor
- we can also use optional first parameter - which will be used as first
y
argument in the function deltas
is-':
minus each prior
scan \
, over /
- little complicated
- their behavior depends on valency of function also on data type of arguments
- scan returns results after each iteration of
f
, over returns result only once after result is converged
monadic function - f
f\[n;x]
- returnsf{x}
,f{f{x}}
and so onn
times- we can also use while clause instead of integer
n
f/[x]
- ifn
is not provided, iterate till output is same as previous result, or till last 2 results are samef\[x]
- iterate(scan) andf/[x]
- converge(over)
dyadic function - f
- function takes 2 arguments
f\[a b c d] = a; f[a;b] f[f[a;b];c] ...
- or we can also provide initial number x -
f\[x;a b c d] = 100+a; 100+f[a;b]; 100+f[f[a;b];c] ..
Exercise
- calculate depreciation of an asset over time
- function :
depr:{[c;r] c*1-r%100}
- depreciation in 1 year
- depreciation in 5 years or
x
years - check with different rate
- different rate, different cost, 1 year
Exercise:
- Question:
Suppose we are given a vector of numbers (xx) and a step size (s). Write a function that will take x and s as arguments, and output a result vector. The result vector is constructed using the following procedure: 1. The xx value sets the mid-point of the step (e.g. if xx is 1 and s is 3, then the values -1,0,1,2 and 3 are included in that step range) 2. If the next xx value is within the current step range, then the step mid-point does not change (e.g. if xx is -1, then the step mid-point is still 1) 3. If the next xx value falls outside the current step range, the step mid-point is reset to that xx value (e.g. if xx is 4, then the new step mid-point is 4) 4. The current step mid-point is stored each time in the result vector Here are two examples to clarify the procedure: xx:1 -1 3 0 1 1 5 6 2 10 s:3 result:1 1 1 1 1 1 5 5 2 10 and xx:2 3 4 3 20 7 8 31 s:6 result:2 2 2 2 20 7 7 31
- Answer:
We will need to introduce 3 parameters: 1. x - the step size (this will take the value s) 2. y - the current step mid-point 3. z - the next value in the xx vector (we will see later how this may be achieved with an adverb) If z is within the current step range, it will satisfy: y - x < z < y + x ; this can be rearranged to give: x > abs ( z - y) So, if x>abs(z-y) is true, then the step mid-point does not change, and the value of y should be saved to the result vector. Alternatively, if x>abs(z-y) is false, then the step mid-point will change to the value of z, and so z should be saved to the result vector. The previous two comments can be expressed as an if-else statement: $[x>abs z - y; y; z] /the value returned, will be the step mid-point Let's digress back to the scan function e.g. q){x+y}\[1 2 3 4] 1 3 6 10 The value returned by the above function is used as the next x value, and the next y value is taken from the next item in the list. This is exactly what we need to do in our problem. Thus, the solution is given by: {$[x>abs z - y; y; z]}[s]\[xx]