Functional coverage tree: Difference between revisions

m
(Moved JS to a more plausible position in the lexicographic sequence)
m ((Moved JS to a more plausible position in the lexicographic sequence))
Line 537:
wine_cellar | 1 | 1.0000 | 0.0000
cinema | 1 | 0.7500 | 0.0167 </pre>
 
 
 
=={{header|J}}==
 
Implementation (raw data):
 
<lang J>raw=: 0 :0
NAME_HIERARCHY |WEIGHT |COVERAGE |
cleaning | | |
house1 |40 | |
bedrooms | |0.25 |
bathrooms | | |
bathroom1 | |0.5 |
bathroom2 | | |
outside_lavatory | |1 |
attic | |0.75 |
kitchen | |0.1 |
living_rooms | | |
lounge | | |
dining_room | | |
conservatory | | |
playroom | |1 |
basement | | |
garage | | |
garden | |0.8 |
house2 |60 | |
upstairs | | |
bedrooms | | |
suite_1 | | |
suite_2 | | |
bedroom_3 | | |
bedroom_4 | | |
bathroom | | |
toilet | | |
attics | |0.6 |
groundfloor | | |
kitchen | | |
living_rooms | | |
lounge | | |
dining_room | | |
conservatory | | |
playroom | | |
wet_room_&_toilet | | |
garage | | |
garden | |0.9 |
hot_tub_suite | |1 |
basement | | |
cellars | |1 |
wine_cellar | |1 |
cinema | |0.75 |
)</lang>
 
Implementation (unpacking raw data):
 
<lang J>labels=: {.<;._2;._2 raw
'hier wspec cspec'=:|:}.<;._2;._2 raw
level=: (%+./) (0 i.~' '&=)"1 hier
weight=: (+ 0=]) ,".wspec
coverage=: ,".cspec</lang>
 
To understand this implementation, it's best to run it and inspect the data.
 
That said:
 
each of the above names is a column variable (with one value for each row in the dataset).
 
level has values 0, 1, 2, 3 or 4 (depending on depth of indent), and the calculation relies on each indent level using the same number of spaces. It might be smarter to use <code>level=: (i.~ ~.) (0 i.~' '&=)"1 hier</code> which only relies on consistent indentation at each level, but ultimately a general case implementation would have to enforce an indentation standard and that sort of mechanism is out of scope for this task.
 
weight fills in the blanks for weights (1 if not otherwise specified). This calculation is simplified because we do not have to worry about any explicitly 0 weights.
 
coverage fills in the blanks for coverage (0 if not otherwise specified).
 
Implementation (translation of leaf coverage to functional coverage):
 
<lang J>merge=: ;@(({.@[,(+}.)~)&.> [: +/\1,_1}.#@>)
unrooted=: ([: merge <@(_1,$:@}.);.1)^:(0<#)
parent=: unrooted level
parent_cover=: (] (1}.~.parent)}~ 1}. * %&(parent +//. ]) [)^:_</lang>
 
<code>unrooted</code> translates indentation information to a [[Tree_traversal#J:_Alternate_implementation|parent tree structure]]. However, the limitations of recursion require we distinguish the parent node from its children, so we use _1 to denote the parent node of the recursive intermediate result unrooted trees. (This works well with using arithmetic to adjust sub-tree indices based on the lengths of preceding sub-trees.) <code>merge</code> combines a boxed sequence of these subtrees to form a single tree - we also rely on the first node of each tree being both _1 and the root node.
 
Thus, <code>parent_cover</code> propagates coverage to parent nodes based on the weighted average of coverage at the children.
 
Task example (format and show result):
 
<lang J> 1 1 }._1 }.":labels,each ":each hier;(,.weight);,.weight parent_cover coverage
NAME_HIERARCHY │WEIGHT │COVERAGE │
cleaning │ 1 │0.409167 │
house1 │40 │ 0.33125 │
bedrooms │ 1 │ 0.25 │
bathrooms │ 1 │ 0.5 │
bathroom1 │ 1 │ 0.5 │
bathroom2 │ 1 │ 0 │
outside_lavatory │ 1 │ 1 │
attic │ 1 │ 0.75 │
kitchen │ 1 │ 0.1 │
living_rooms │ 1 │ 0.25 │
lounge │ 1 │ 0 │
dining_room │ 1 │ 0 │
conservatory │ 1 │ 0 │
playroom │ 1 │ 1 │
basement │ 1 │ 0 │
garage │ 1 │ 0 │
garden │ 1 │ 0.8 │
house2 │60 │0.461111 │
upstairs │ 1 │ 0.15 │
bedrooms │ 1 │ 0 │
suite_1 │ 1 │ 0 │
suite_2 │ 1 │ 0 │
bedroom_3 │ 1 │ 0 │
bedroom_4 │ 1 │ 0 │
bathroom │ 1 │ 0 │
toilet │ 1 │ 0 │
attics │ 1 │ 0.6 │
groundfloor │ 1 │0.316667 │
kitchen │ 1 │ 0 │
living_rooms │ 1 │ 0 │
lounge │ 1 │ 0 │
dining_room │ 1 │ 0 │
conservatory │ 1 │ 0 │
playroom │ 1 │ 0 │
wet_room_&_toilet │ 1 │ 0 │
garage │ 1 │ 0 │
garden │ 1 │ 0.9 │
hot_tub_suite │ 1 │ 1 │
basement │ 1 │0.916667 │
cellars │ 1 │ 1 │
wine_cellar │ 1 │ 1 │
cinema │ 1 │ 0.75 │</lang>
 
Extra credit:
 
<lang J>trace=: (~.@,each (0 >. parent)&{)^:_ i.#parent
power=: */@:{&(parent (] % (i.~ ~.)@[ { +//.) weight)@> trace
 
power*1-weight parent_cover coverage
0.590833 0.2675 0.0375 0.025 0.00833333 0.0166667 0 0.0125 0.045 0.0375 0.0125 0.0125 0.0125 0 0.05 0.05 0.01 0.323333 0.17 0.05 0.0125 0.0125 0.0125 0.0125 0.05 0.05 0.02 0.136667 0.0333333 0.0333333 0.00833333 0.00833333 0.00833333 0.00833333 0.0333333 0.0333333 0.00333333 0 0.0166667 0 0 0.0166667</lang>
 
Explanation:
 
<code>trace</code> is, for each node, the set of nodes (or indices of nodes - since we use indices to identify nodes) leading from that node to its root.
 
<code>parent (] % (i.~ ~.)@[ { +//.) weight</code> is the weight of each node divided by the total weight for all nodes with the same parent.
 
<code>power</code> is the product of these relative weights for each member of the trace.
 
And, <code>weight parent_cover coverage</code> was the functional coverage for each node.
 
 
=={{header|JavaScript}}==
Line 1,027 ⟶ 1,176:
cinema | 1 | 0.7500 | 0.0167 </pre>
 
=={{header|J}}==
 
Implementation (raw data):
 
<lang J>raw=: 0 :0
NAME_HIERARCHY |WEIGHT |COVERAGE |
cleaning | | |
house1 |40 | |
bedrooms | |0.25 |
bathrooms | | |
bathroom1 | |0.5 |
bathroom2 | | |
outside_lavatory | |1 |
attic | |0.75 |
kitchen | |0.1 |
living_rooms | | |
lounge | | |
dining_room | | |
conservatory | | |
playroom | |1 |
basement | | |
garage | | |
garden | |0.8 |
house2 |60 | |
upstairs | | |
bedrooms | | |
suite_1 | | |
suite_2 | | |
bedroom_3 | | |
bedroom_4 | | |
bathroom | | |
toilet | | |
attics | |0.6 |
groundfloor | | |
kitchen | | |
living_rooms | | |
lounge | | |
dining_room | | |
conservatory | | |
playroom | | |
wet_room_&_toilet | | |
garage | | |
garden | |0.9 |
hot_tub_suite | |1 |
basement | | |
cellars | |1 |
wine_cellar | |1 |
cinema | |0.75 |
)</lang>
 
Implementation (unpacking raw data):
 
<lang J>labels=: {.<;._2;._2 raw
'hier wspec cspec'=:|:}.<;._2;._2 raw
level=: (%+./) (0 i.~' '&=)"1 hier
weight=: (+ 0=]) ,".wspec
coverage=: ,".cspec</lang>
 
To understand this implementation, it's best to run it and inspect the data.
 
That said:
 
each of the above names is a column variable (with one value for each row in the dataset).
 
level has values 0, 1, 2, 3 or 4 (depending on depth of indent), and the calculation relies on each indent level using the same number of spaces. It might be smarter to use <code>level=: (i.~ ~.) (0 i.~' '&=)"1 hier</code> which only relies on consistent indentation at each level, but ultimately a general case implementation would have to enforce an indentation standard and that sort of mechanism is out of scope for this task.
 
weight fills in the blanks for weights (1 if not otherwise specified). This calculation is simplified because we do not have to worry about any explicitly 0 weights.
 
coverage fills in the blanks for coverage (0 if not otherwise specified).
 
Implementation (translation of leaf coverage to functional coverage):
 
<lang J>merge=: ;@(({.@[,(+}.)~)&.> [: +/\1,_1}.#@>)
unrooted=: ([: merge <@(_1,$:@}.);.1)^:(0<#)
parent=: unrooted level
parent_cover=: (] (1}.~.parent)}~ 1}. * %&(parent +//. ]) [)^:_</lang>
 
<code>unrooted</code> translates indentation information to a [[Tree_traversal#J:_Alternate_implementation|parent tree structure]]. However, the limitations of recursion require we distinguish the parent node from its children, so we use _1 to denote the parent node of the recursive intermediate result unrooted trees. (This works well with using arithmetic to adjust sub-tree indices based on the lengths of preceding sub-trees.) <code>merge</code> combines a boxed sequence of these subtrees to form a single tree - we also rely on the first node of each tree being both _1 and the root node.
 
Thus, <code>parent_cover</code> propagates coverage to parent nodes based on the weighted average of coverage at the children.
 
Task example (format and show result):
 
<lang J> 1 1 }._1 }.":labels,each ":each hier;(,.weight);,.weight parent_cover coverage
NAME_HIERARCHY │WEIGHT │COVERAGE │
cleaning │ 1 │0.409167 │
house1 │40 │ 0.33125 │
bedrooms │ 1 │ 0.25 │
bathrooms │ 1 │ 0.5 │
bathroom1 │ 1 │ 0.5 │
bathroom2 │ 1 │ 0 │
outside_lavatory │ 1 │ 1 │
attic │ 1 │ 0.75 │
kitchen │ 1 │ 0.1 │
living_rooms │ 1 │ 0.25 │
lounge │ 1 │ 0 │
dining_room │ 1 │ 0 │
conservatory │ 1 │ 0 │
playroom │ 1 │ 1 │
basement │ 1 │ 0 │
garage │ 1 │ 0 │
garden │ 1 │ 0.8 │
house2 │60 │0.461111 │
upstairs │ 1 │ 0.15 │
bedrooms │ 1 │ 0 │
suite_1 │ 1 │ 0 │
suite_2 │ 1 │ 0 │
bedroom_3 │ 1 │ 0 │
bedroom_4 │ 1 │ 0 │
bathroom │ 1 │ 0 │
toilet │ 1 │ 0 │
attics │ 1 │ 0.6 │
groundfloor │ 1 │0.316667 │
kitchen │ 1 │ 0 │
living_rooms │ 1 │ 0 │
lounge │ 1 │ 0 │
dining_room │ 1 │ 0 │
conservatory │ 1 │ 0 │
playroom │ 1 │ 0 │
wet_room_&_toilet │ 1 │ 0 │
garage │ 1 │ 0 │
garden │ 1 │ 0.9 │
hot_tub_suite │ 1 │ 1 │
basement │ 1 │0.916667 │
cellars │ 1 │ 1 │
wine_cellar │ 1 │ 1 │
cinema │ 1 │ 0.75 │</lang>
 
Extra credit:
 
<lang J>trace=: (~.@,each (0 >. parent)&{)^:_ i.#parent
power=: */@:{&(parent (] % (i.~ ~.)@[ { +//.) weight)@> trace
 
power*1-weight parent_cover coverage
0.590833 0.2675 0.0375 0.025 0.00833333 0.0166667 0 0.0125 0.045 0.0375 0.0125 0.0125 0.0125 0 0.05 0.05 0.01 0.323333 0.17 0.05 0.0125 0.0125 0.0125 0.0125 0.05 0.05 0.02 0.136667 0.0333333 0.0333333 0.00833333 0.00833333 0.00833333 0.00833333 0.0333333 0.0333333 0.00333333 0 0.0166667 0 0 0.0166667</lang>
 
Explanation:
 
<code>trace</code> is, for each node, the set of nodes (or indices of nodes - since we use indices to identify nodes) leading from that node to its root.
 
<code>parent (] % (i.~ ~.)@[ { +//.) weight</code> is the weight of each node divided by the total weight for all nodes with the same parent.
 
<code>power</code> is the product of these relative weights for each member of the trace.
 
And, <code>weight parent_cover coverage</code> was the functional coverage for each node.
 
=={{header|Julia}}==
9,655

edits