Explanation of merge function - merge

I saw some pseudocode in some old exam and I can't really figure out what it's doing.
Can anyone explain it to me?
A and B are BST's.
Foo(A,B)
if A= NULL
return B
if B != NULL
if value[A] > value[B]
return Foo(B,A)
left[B] <- Foo(right[A],left[B])
right[A] <- B
return A

This is a binary search tree merge routine. If either A or B is null (representing an empty tree), it returns the other. Otherwise, it makes sure that the root of A is less than the root of B; if the roots are in the wrong order, it recurses with the arguments swapped. Then, it recursively merges the right subtree of A and the left subtree of B, and attaches the result as the left subtree of B. Finally, it attaches B as the new right subtree of A and returns A.

Related

Access table content from a return table function

I have a probleme where a user have to lookup a trajectory to go from point A to point B.
What i have to do is look up a way to go from point A to B via other points, like maybe A>C>B.
To do this i basically take the first point which is A and then check all the available point to go towards from this point.
Ex : maybee from point A, i can go to C, D and E
Then i look if one of the result is equal to B. If not, i then call this function again from the next points, in this case : C then D then E and this recursively until i find a way to go from A to B
I first made a recursive function function(A, B) that returns a table od points i've been too like explained above but the problem was, the point A could go to C and C could go to A so it was recursively looping from A to C and then C to A over and over again. So now i have to find a way to check if a point have alreay been travelled to.
so my function returns table(start, finish). If i to the trajectory A>C>D>E>B for example, then in the table i'll have the lines :
START FINISH
A > C
C > D
D > E
E > B
now I have NO IDEA how to check in this table that i'm returning to see if a value is in this table or not example : to check on the third iteration if i've already been in point C so that i don't go from D to C.
I'm really sorry if this is not clear enough, it's not super clear in my head also.
create or replace function findConnection(starting, ending) RETURNS TABLE (v_starting, v_ending)
as $$
declare
temp record;
begin
for temp in select start, end from trip where start = starting
loop
if temp.end = ending then
v_starting := temp.start;
v_ending := temp.end;
else
/* here i should check if i've already been threw this point
something like : if select * from table where v_starting = temp.end != null then */
v_starting := temp.start;
v_ending := temp.end;
return next;
findConnection(temp.end, ending); /*recursive call for the next points*/
end if;
end loop;
end;
language plpgsql;

Applying an operation on each element of nested list

I have a complex nested list (depth can be >2 also):
p:((`g;`d1`d2);(`r;enlist `e1);(`r;enlist `p1))
How to add an element to each element of the nested list but retaining the original structure; e.g. adding `h to each element of p to get the following :
((`g`h;(`d1`h;`d2`h));(`r`h;enlist `e1`h);(`r`h;enlist `p1`h))
I tried this but doesn't give what I want :
q)p,\:`h
((`g;`d1`d2;`h);(`r;enlist `e1;`h);(`r;enlist `p1;`h))
q)raze[p],\:`h
(`g`h;`d1`d2`h;`r`h;`e1`h;`r`h;`p1`h)
You can use .z.s to recursively go through the nested list and only append `h to lists of symbols:
q){$[0=type x;.z.s'[x];x,\:`h]}p
g h d1 h d2 h
`r`h ,`e1`h
`r`h ,`p1`h
For this function I have made the assumption that your nested lists will only contain symbols. It checks the type of the list, if it is not a mixed list then it appends `h to each element. If it is a mixed list then it passes each element of that list back into the function separately to check again.
Although not recursive (and so requires some knowledge about the shape of your nested list), a more conventional approach would be
q).[p;2#(::);,';`h]
g h d1 h d2 h
`r`h ,`e1`h
`r`h ,`p1`h
Though Thomas has already answered the question; In case you want to specify any other operation apart from append, you can use the following :
q)f:{`$ "_" sv string x,y}
q){[o;a;e] $[-11<>type e; .z.s [o;a] each e; o[e;a]] }[f;`h] each p
`g_h `d1_h`d2_h
`r_h ,`e1_h
`r_h ,`p1_h
or when f is assigned as append operation
q)f:{x,y}
q){[o;a;e] $[-11<>type e; .z.s [o;a] each e; o[e;a]] }[f;`h] each p
g h d1 h d2 h
`r`h ,`e1`h
`r`h ,`p1`h

Traversing a tree and assigning a subtree in Julia

I am trying to manipulate a tree in Julia. The tree is created as an object. All I want is substituting the one of the branches with another one. I can do it manually but can not do it by using a recursion function.
mutable struct ILeaf
majority::Any # +1 when prediction is correct
values::Vector # num_of_samples
indicies::Any # holds the index of training samples
end
mutable struct INode
featid::Integer
featval::Any
left::Union{ILeaf,INode}
right::Union{ILeaf,INode}
end
ILeafOrNode = Union{ILeaf,INode}
And my function for chaning the tree is (tree is original one where, by using LR_STACK, I am willing to change one of the branches and substitute it with the subtree. ) :
function traverse_and_assign(tree, subtree, lr_stack) # by using Global LR_stack
if top(lr_stack) == 0
tree = subtree
elseif top(lr_stack) == :LEFT
pop!(lr_stack)
return traverse_and_assign(tree.left, subtree, lr_stack)
else # right otherwise
pop!(lr_stack)
return traverse_and_assign(tree.right, lr_stack)
end
end
What happens is that I cannot change the original tree.
On the other hand :
tree.left.left = subtree
works perfectly fine.
What is wrong with my code ? Do I have to write a macro for this ?
B.R.
edit#1
In order to generate data :
n, m = 10^3, 5 ;
features = randn(n, m);
lables = rand(1:2, n);
edit#2
use 100 samples for training the decision tree :
base_learner = build_iterative_tree(labels, features, [1:20;])
then give other samples one by one :
i = 21
feature = features[21, :], label = labels[21]
gtree_stack, lr_stack = enter_iterate_on_tree(base_learner, feature[:], i, label[1])
get the indices of incorrect samples
ids = subtree_ids(gtree_stack)
build the subtree:
subtree = build_iterative_tree(l, f, ids)
update the original tree(base_learner):
traverse_and_assign(base_learner, subtree, lr_stack)
I still miss MWE but maybe I could help with one problem without it.
In Julia value is bind to variable. Parameters in functions are new variables. Let's do test what does it mean:
function test_assign!(tree, subtree)
tree = subtree
return tree
end
a = 4;
b = 5;
test_assign!(a, b) # return 5
show(a) # 4 ! a is not changed!
What happend? value 4 was bind to tree and value 5 was bind to subtree.
subtree's value (5) was bind to tree.
And nothing else! Means a is stil bound to 4.
How to could we change a? This will work:
mutable struct SimplifiedNode
featid::Integer
end
function test_assign!(tree, subtree)
tree.featid = subtree.featid
end
a = SimplifiedNode(4)
b = SimplifiedNode(5)
test_assign!(a, b)
show(a) # SimplifiedNode(5)
Why? What happend?
Value of a (which is something like pointer to mutable struct) is bind to tree and value of b is bound to subtree.
So a and tree are bound to same structure! Means that if we change that structure a is bind to changed structure.

Replacement of numbers

I am given three variables having finite values ( all are integers) m,n, r.
Now I need to do m<-r and n<-r ( assign m and n the value of r ) and I have read in "The Art of Computer Programming vol. 1 " that the operations can be combined as
m<-n<-r
But will the above statement not mean "assign m the value of n and then n the value of r".
Thanks in advance.
The order of assignment is from right to left. Thus, m<-n<-r will be interpreted as: n<-r and then m<-n.
Since n equals r after the first assignment, m<-n and m<-r are identical.
Assignment = operator is like assigning the right side value to left side. For eg
int a = 1 + 2;
Here first 1+2 is evaluated and assigned to a because it follows right to left associativity.
Now if you have something like this
int a=b=2;
It again follows right to left associativity. From right first b=2 is evaluated and assign 2 to b then b is assigned to a. It works like this a=(b=2)
Know in your question you have m<-n<-r . This will work like this m<-(n<-r)
You can see reference Operator Associativity

How to replace/modify something in a call to function 1 from within function 2 (both in their separate files)

The given task is to call a function from within another function, where both functions are handling matrices.
Now lets call this function 1 which is in its own file:
A = (1/dot(v,v))*(Ps'*Ps);
Function 1 is called with the command:
bpt = matok(P);
Now in another file in the same folder where function 1 is located (matok.m) we make another file containing function 2 that calls function 1:
bpt = matok(P);
What I wish B to do technically, is to return the result of the following (where D is a diagonal matrix):
IGNORE THIS LINE: B = (1/dot(v,v))*(Ps'*inv(D)*Ps*inv(D);
EDIT: this is the correct B = (1/dot(v,v))*(Ps*inv(D))'*Ps*inv(D);
But B should not "re-code" what has allready been written in function 1, the challenge/task is to call function 1 within function 2, and within function 2 we use the output of function 1 to end up with the result that B gives us. Also cause in the matrix world, AB is not equal to BA, then I can't simply multiply with inv(D) twice in the end. Now since Im not allowed to write B as is shown above, I was thinking of replacing (without altering function 1, doing the manipulation within function 2):
(Ps'*Ps)
with
(Ps'*inv(D)*Ps*inv(D)
which in some way I imagine should be possible, but since Im new to Matlab have no idea how to do or where even to start. Any ideas on how to achieve the desired result?
A small detail I missed:
The transpose shouldn't be of Ps in this:
B = (1/dot(v,v))*(Ps'*inv(D))*Ps*inv(D);
But rather the transpose of Ps and inv(D):
B = (1/dot(v,v))*(Ps*inv(D))'*Ps*inv(D);
I found this solution, but it might not be as compressed as it could've been and it seems a bit unelegant in my eyes, maybe there is an even shorter way?:
C = pinv(Ps') * A
E = (Ps*inv(D))' * C
Since (A*B)' = B'*A', you probably just need to call
matok(inv(D) * Ps)