Why does loop variable in repeat not work - red

Loop variable of repeat can be used in its block like this:
>> b: func [x] [x + i]
== func [x][x + i]
>> repeat i 2 [print reduce append copy [b] [3]]
4
5
You can see that the variable "i" is used by the function "b".
However,in the following example, the loop variable "idx" is not seen by the function. Error message is given:
*** Script Error: idx has no value
Red []
map: function [a-func a-block][
result: [] args: [] clear result
either parse a-block [some block!][
repeat idx length? a-block/1 [
clear args
foreach x a-block [append args to-block x/:idx]
append result reduce append copy [a-func] args
]
return result
]
[
repeat idx length? a-block [
append result to-block a-func a-block/:idx
]
]
]
map func [x y] [x + y - idx] [[1 2] [3 4]]
Why is the second code wrong? And how to make it working?

Loop variable of repeat can be used in its block like this
Unfortunately, this is conceptually wrong. Loop "variable" is not used in the block, it is "globally visible" both to function's body block and to repeat.
>> repeat index 5 []
>> index
== 5
Diagrammatically, that's lambda → <idx in global context> ← repeat, not lambda → repeat → <idx in repeat's "scope"> as you probably think.
However,in the following example, the loop variable "idx" is not seen by the function.
This is because you are using function constructor, which makes idx word local to its context, like so:
>> function [][repeat index 3 []]
== func [/local index][repeat index 3 []]
By contrast, func (used in your first example) doesn't do that.
>> func [][repeat index 3 []]
== func [][repeat index 3 []]
That is, in this code:
map func [x y] [x + y - idx] [[1 2] [3 4]]
idx within the anonymous function that you map over the block and idx in map implementation are two completely different "variables", bound to different contexts: one to the global (in which it has no value, hence the error message), and another to a local (where it is set to none by default).
The mechanics of Red's "scoping" model (or rather complete absence thereof) is a bit of an advanced topic, though I can elaborate on it if needed.
Suffice to say that it does not rely on traditional lexical scoping (like in most of the Lisp dialects), nor does it have variables in the strict sense of the term. Rather, it relies on symbolic values (aka words) that carry with them a binding to namespaces (aka contexts), which can be changed at will during the runtime (see bind in the example below) — a bit like f-expressions in Kernel and older Lisps, or perhaps anaphoric macro, of which collect (see below also) is a prime example: note that it "captures" keep word, which from then on refers to its internal context, where it is defined as an ad-hoc alias for append. Check out source collect output to see what I mean.
Here's a sketch of map (yours technically is more like zip, but anyway) to give you a hint at the potential solution.
map: function [
function [function!]
series [series!]
][
spec: spec-of :function ; ideally needs to be cleaned up
step: length? spec
index: 1
bind body-of :function 'index
collect [
foreach :spec series [
keep/only do compose [(:function) (:spec)]
index: index + step
]
]
]
Example:
>> map func [x] [reduce [index x]][a b c d]
== [[1 a] [2 b] [3 c] [4 d]]
>> map func [x y] [reduce [index x + y - index]][9 2 1 4]
== [[1 10] [3 2]]

Related

Iterate (/) a multivalent function

How do you iterate a function of multivalent rank (>1), e.g. f:{[x;y] ...} where the function inputs in the next iteration step depend on the last iteration step? Examples in the reference manual only iterate unary functions.
I was able to achieve this indirectly (and verbosely) by passing a dictionary of arguments (state) into unary function:
f:{[arg] key[arg]!(min arg;arg[`y]-2)}
f/[{0<x`x};`x`y!6 3]
Note that projection, e.g. f[x;]/[whilecond;y] would only work in the scenario where the x in the next iteration step does not depend on the result of the last iteration (i.e. when x is path-independent).
In relation to Rahul's answer, you could use one of the following (slightly less verbose) methods to achieve the same result:
q)g:{(min x,y;y-2)}
q)(g .)/[{0<x 0};6 3]
-1 -3
q).[g]/[{0<x 0};6 3]
-1 -3
Alternatively, you could use the .z.s self function, which recursively calls the function g and takes the output of the last iteration as its arguments. For example,
q)g:{[x;y] x: min x,y; y:y-2; $[x<0; (x;y); .z.s[x;y]]}
q)g[6;3]
-1 -3
Function that is used with '/' and '\' can only accept result from last iteration as a single item which means only 1 function parameter is reserved for the result. It is unary in that sense.
For function whose multiple input parameters depends on last iteration result, one solution is to wrap that function inside a unary function and use apply operator to execute that function on the last iteration result.
Ex:
q) g:{(min x,y;y-2)} / function with rank 2
q) f:{x . y}[g;] / function g wrapped inside unary function to iterate
q) f/[{0<x 0};6 3]
Over time I stumbled upon even shorter way which does not require parentheses or brackets:
q)g:{(min x,y;y-2)}
q){0<x 0} g//6 3
-1 -3
Why does double over (//) work ? The / adverb can sometimes be used in place of the . (apply) operator:
q)(*) . 2 3
6
q)(*/) 2 3
6

KDB+/Q: About unused parameters in inner functions

I have this function f
f:{{z+x*y}[x]/[y]}
I am able to call f without a 3rd parameter and I get that, but how is the inner {z+x*y} able to complete without a third parameter?
kdb will assume, if given a single list to a function which takes two parameters, that you want the first one to be x and the remainder to be y (within the context of over and scan, not in general). For example:
q){x+y}/[1;2 3 4]
10
can also be achieved by:
q){x+y}/[1 2 3 4]
10
This is likely what's happening in your example.
EDIT:
In particular, you would use this function like
q){{z+x*y}[x]/[y]}[2;3 4 5 6]
56
which is equivalent to (due to the projection of x):
q){y+2*x}/[3 4 5 6]
56
which is equivalent to (due to my original point above):
q){y+2*x}/[3;4 5 6]
56
Which explains why the "third" parameter wasn't needed
You need to understand 2 things: 'over' behavior with dyadic functions and projection.
1. Understand how over/scan works on dyadic function:
http://code.kx.com/q/ref/adverbs/#over
If you have a list like (x1,x2,x3) and funtion 'f' then
f/(x1,x2,x3) ~ f[ f[x1;x2];x3]
So in every iteration it takes one element from list which will be 'y' and result from last iteration will be 'x'. Except in first iteration where first element will be 'x' and second 'y'.
Ex:
q) f:{x*y} / call with -> f/ (4 5 6)
first iteration : x=4, y=5, result=20
second iteration: x=20, y=6, result=120
2. Projection:
Lets take an example funtion f3 which takes 3 parameters:
q) f3:{[a;b;c] a+b+c}
now we can project it to f2 by fixing (passing) one parameter
q) f2:f3[4] / which means=> f2={[b;c] 4+b+c}
so f2 is dyadic now- it accepts only 2 parameters.
So now coming to your example and applying above 2 concepts, inner function will eventually become dyadic because of projection and then finally 'over' function works on this new dyadic function.
We can rewrite the function as :
f:{
f3:{z+x*y};
f2:f3[x];
f2/y
}

Issue with NetLogo map

When I enter (map [?1 + ?2] [1 2 3] [2 4 6]) into the command center, it works fine. But when I enter this code
to test
(map [?1 + ?2] [1 2 3] [2 4 6])
end
I get the diagnostic: "Expected command." with map highlighted. I'm stumped. Suggestions would be appreciated. Thanks.
(I'm using NetLogo 5.1.0.)
The problem is that map is not considered a command (as the diagnostic says). When I replace map with foreach (and put the function at the end) it's fine.
In fact, that's what I really wanted in the first place. I was using map for it's side-effects of running through multiple lists rather than to return a list. My mistake.
For user convenience, the command center allows you to set the "context" of your commands and does a little extra interpretation depending on that context. The problem is not that the map reporter is failing, but that it reports a list, and you need a command saying what to do with that list.
After you enter (map [?1 + ?2] [1 2 3] [2 4 6]) in the command center, look not just at the result but also at the code actually executed (right above the result). If you put that code in your test procedure, it will work.
you code does not work because you are producing a new list with map but you are not assigning that list to any variable. You are right that map is not a command primitive, it is a reporter primitive, so it returns a value and you have to put that value somewhere, like print it on the screen:
to test
print (map [?1 + ?2] [1 2 3] [2 4 6])
end
or store it in a variable:
to test
let a-variable (map [?1 + ?2] [1 2 3] [2 4 6])
print a-variable
end

Define a set of functions by means of for loops in Maple

In Maple, I want to define a set of functions by means of two for loops:
printlevel:=2;
# Node coordinates.
N_x:=5;
N_y:=4;
N_elx:=N_x-1;
N_ely:=N_y-1;
h_x:=(x_e-x_s)/N_elx;
h_y:=(y_e-y_s)/N_ely;
x_n:=[seq(x_s+j*h_x,j=0..N_elx)];
y_n:=[seq(y_s+j*h_y,j=0..N_ely)];
# Partition of unity.
for j from 2 by 1 to N_x-1 do
for k from 2 by 1 to N_y-1 do
phi[j,k]:=(x,y)->(x-x_n[j-1])*(x-x_n[j+1])*(y-y_n[k-1])*(y-y_n[k+1])/((x_n[j]-x_n[j-1])*(x_n[j]-x_n[j+1])*(y_n[k]-y_n[k-1])*(y_n[k]-y_n[k+1]));
od;
od;
However, this gives output in which the [j,k] vary but the x_n[j-1], x_n[j+1], y_n[j-1] and y_n[j+1] are not evaluated. Consequently, the functions are not defined properly. For instance, calling the j=4,k=2 function with phi[4,2](x,y);, I get the output
phi[4, 2] called with arguments: x, y
#(phi[4,2],1): (x-x_n[j-1])*(x-x_n[j+1])*(y-y_n[k-1])*(y-y_n[k+1])/(x_n[j]-x_n[j-1])/(x_n[j]-x_n[j+1])/(y_n[k]-y_n[k-1])/(y_n[k]-y_n[k+1])
Error, (in phi[4, 2]) invalid subscript selector
instead of the desired output
$\phi_{4,2}:=\dfrac{(x-x_3)(x-x_5)(y-y_1)(y-y_3)}{(x_4-x_3)(x_4-x_5)(y_2-y_1)(y_2-y_3)}=\dfrac{(x-\dfrac{1}{2})(x-1)(y-0)(y-\dfrac{2}{3})}{(\dfrac{3}{4}-\dfrac{1}{2})(\dfrac{3}{4}-1)/(\dfrac{1}{3}-0)(\dfrac{1}{3}-\dfrac{2}{3})}$
How do I solve this?
Answer from acer:
If you want operators instead of expressions, use the function unapply:
N_x:=5;
N_y:=4;
N_elx:=N_x-1;
N_ely:=N_y-1;
h_x:=(x_e-x_s)/N_elx;
h_y:=(y_e-y_s)/N_ely;
x_n:=[seq(x_s+j*h_x,j=0..N_elx)];
y_n:=[seq(y_s+j*h_y,j=0..N_ely)];
# Partition of unity.
for j from 2 by 1 to N_x-1 do
for k from 2 by 1 to N_y-1 do
phi[j,k]:=unapply( (x-x_n[j-1])*(x-x_n[j+1])
*(y-y_n[k-1])*(y-y_n[k+1])
/((x_n[j]-x_n[j-1])*(x_n[j]-x_n[j+1])
*(y_n[k]-y_n[k-1])*(y_n[k]-y_n[k+1])),
[x,y]);
od;
od;

Subsref with cells

This issue appeared when I was answering this question. It should be some stupid error I am doing, but I can't get what error it is…
myMatrix = [22 33; 44 55]
Returns:
>> subsref(myMatrix, struct('type','()','subs',{{[1 2]}} ) );
ans =
22 44
While using it with cells:
myCell = {2 3; 4 5}
Returns:
>> subsref(myCell,struct('type','{}','subs',{{[1 2]}} ) );
ans =
2 % WHATTT?? Shouldn't this be 2 and 4 Matlab??
Checking the subsref documentation, we see:
See how MATLAB calls subsref for the expression:
A{1:2} The syntax A{1:2} calls B = subsref(A,S) where S.type='{}' and
S.subs={[1 2]}.
This seems not to be true because the returned value by subsref is just the first argument, not all arguments.
Then if one does:
>> [a,b]=subsref(myCell,struct('type','{}','subs',{{[1 2]}} ) )
a =
2
b =
4 % Surprise!
But this is not the same as myCell{[2 4]} which will automatically return:
>> myCell{[1 2]}
ans =
2
ans =
4
I would need to use subsref with one output for every index I use access myCell, or am I missing something?
When the curly braces ({}) are used for indexing a cell array, the output is a comma-separated list. This implicitly calls subsref but the behavior is slightly different from invoking it directly.
subsref by itself is a technically a function, and the comma-separated list returned by the curly braces simply behaves like varargout in this case. This means that you should specify an appropriate "sink" for all desired output results, just like you would do with any other function returning multiple parameters, otherwise they would be ignored.
dont ask me why, this is just something I tried:
myOutput=subsref(myCell,struct('type','()','subs',{{[1 2]}} ) )
note the 'type','()'!
this gives me:
myOutput =
[2] [4]
with myOutput as cell. Converting back:
>> myOutput=cell2mat(subsref(myCell,struct('type','()','subs',{{[1 2]}})))
myOutput =
2 4
This is just a "fast" answer, that will need some improvements or some background-info as well...
I was further investigating #EitanH answer and managed to find more details.
Yeah, it returns a comma separed list, but the function subsref should return a comma separed list just the A{:} does. Here is an example where the functions behave different, but this is an expected behavior, I would like the class .get method to return a list and one class common function to behave as common functions getting only the first argument from the cell.
classdef ListReturn
properties(Access = private)
a
end
properties(Dependent)
getA
end
methods
function self = ListReturn(a)
self.a = a;
end
function varargout = get.getA(self)
varargout = {self.a};
end
function varargout = getAFcn(self)
varargout = {self.a};
end
end
end
There is a substantial difference when calling the functions, exactly as the .get:
k=[ListReturn(2) ListReturn(3) ListReturn(4) ListReturn(5)]
>> k.getAFcn
ans =
2
>> k.getA
ans =
2
ans =
3
ans =
4
ans =
5
So it seems that using A{1:2} or A{:} works like a Cell.get(), whereas the subsref works as a common matlab function, returning only one argument when the output arguments are not specified, as one function in C,java,C++ would do. Anyway, I just feel like subsref should work as the .get.