w2v-server: introduce position heats for collocators
diff --git a/templates/index.html.ep b/templates/index.html.ep
index 33579fd..7e5fb95 100644
--- a/templates/index.html.ep
+++ b/templates/index.html.ep
@@ -11,194 +11,211 @@
<link rel="stylesheet" href="https://cdn.datatables.net/1.10.16/css/jquery.dataTables.min.css">
<script
src="http://code.jquery.com/ui/1.12.1/jquery-ui.min.js"
- integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU="
- crossorigin="anonymous"></script>
+ integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU="
+ crossorigin="anonymous"></script>
<script>
var urlParams = new URLSearchParams(window.location.search);
$('#firstable').hide();
$(document).ready(function() {
- $("input").bind("keydown", function(event) {
- // track enter key
- var keycode = (event.keyCode ? event.keyCode : (event.which ? event.which : event.charCode));
- if (keycode == 13) { // keycode for enter key
- // force the 'Enter Key' to implicitly click the Update button
- document.getElementById('SEARCH').click();
- return false;
- } else {
- return true;
- }});
+ $("input").bind("keydown", function(event) {
+ // track enter key
+ var keycode = (event.keyCode ? event.keyCode : (event.which ? event.which : event.charCode));
+ if (keycode == 13) { // keycode for enter key
+ // force the 'Enter Key' to implicitly click the Update button
+ document.getElementById('SEARCH').click();
+ return false;
+ } else {
+ return true;
+ }});
- $(".selector").tabs({ active: 1 });
+ $(".selector").tabs({ active: 1 });
- $('#firsttable').DataTable({
- "sScrollY": "780px",
- "bScrollCollapse": true,
- "bPaginate": false,
- "bJQueryUI": true,
- "dom": '<"top">rt<"bottom"flp><"clear">',
- "aoColumnDefs": [
- { "sWidth": "10%", "aTargets": [ -1 ] }
- ]
+ $('#firsttable').DataTable({
+ "sScrollY": "780px",
+ "bScrollCollapse": true,
+ "bPaginate": false,
+ "bJQueryUI": true,
+ "dom": '<"top">rt<"bottom"flp><"clear">',
+ "aoColumnDefs": [
+ { "sWidth": "10%", "aTargets": [ -1 ] }
+ ]
+ } );
+
+ $( "#first" ).clone().prependTo( "#tabs-2" );
+
+ function changeCharColor(txt, heat) {
+ var newText = "";
+ for (var i=0, l=txt.length; i<l; i++) {
+ newText += '<span style="background-color:'+getHeatColor(heat[i]/maxHeat)+'">'+txt.charAt(i)+'</span>';
+ }
+ return newText;
+ }
+
+ function getHeatColor(value) {
+ var hue=((1-value)*120).toString(10);
+ return ["hsl(",hue,",100%,50%)"].join("");
+ }
+
+ function bitvec2window(n, heat) {
+ var str = n.toString(2).padStart(10, "0")
+ .replace(/^([0-9]{5})/, '$1x')
+ .replace(/0/g, '·')
+ .replace(/1/g, '+');
+ return changeCharColor(str, heat);
+ }
+
+ var collocatorData = <%= b(Mojo::JSON::to_json($collocators)) %>;
+ var maxHeat; // = Math.max.apply(Math,collocatorData.map(function(o){return o.cprob;}))
+ maxHeat = Math.max.apply(Math,collocatorData.map(function(o){return Math.max.apply(Math,o.heat);}))
+
+ if (collocatorData != null) {
+ var t = $('#secondtable').DataTable({
+ data: collocatorData,
+ "sScrollY": "800px",
+ "bScrollCollapse": true,
+ "bPaginate": false,
+ "bJQueryUI": true,
+ "dom": '<"top">rt<"bottom"flp><"clear">',
+ "columns": [
+ { "data": "rank", type: "allnumeric" },
+ { "data": "pos", width: "7%", sClass: "dt-center mono compact", render: function ( data, type, row ) {return bitvec2window(data, row.heat) }},
+ { "data": "max", render: function ( data, type, row ) {return data.toFixed(3) }},
+ { "data": "conorm", render: function ( data, type, row ) {return data.toFixed(3) }},
+ { "data": "prob", type: "scientific", render: function ( data, type, row ) {return data.toExponential(3) } },
+ { "data": "cprob", type: "scientific", render: function ( data, type, row ) {return data.toExponential(3) } },
+ { "data": "overall", type: "scientific", render: function ( data, type, row ) {return data.toExponential(3) } },
+ { "data": "word", sClass: "collocator" }
+ ],
+ "columnDefs": [
+ { className: "dt-right", "targets": [0,2,3,4,5,6] },
+ { className: "dt-center", "targets": [ 1] },
+ { "searchable": false,
+ "orderable": false,
+ "targets": 0
+ },
+ { "type": "scientific", targets: [2,3,4,5,6] },
+ { "orderSequence": [ "desc" ], "targets": [ 2, 3, 4, 5, 6 ] },
+ { "orderSequence": [ "asc", "desc" ], "targets": [ 1, 7 ] },
+ ],
+ "order": [[ 4, 'desc' ]],
} );
- function bitvec2window(n) {
- var str = n.toString(2).padStart(10, "0")
- .replace(/^([0-9]{5})/, '$1x')
- .replace(/0/g, '·')
- .replace(/1/g, '+');
- return str;
- }
-
- var collocatorData = <%= b(Mojo::JSON::to_json($collocators)) %>;
-
- if (collocatorData != null) {
- var t = $('#secondtable').DataTable({
- data: collocatorData,
- "sScrollY": "800px",
- "bScrollCollapse": true,
- "bPaginate": false,
- "bJQueryUI": true,
- "dom": '<"top">rt<"bottom"flp><"clear">',
- "columns": [
- { "data": "rank", type: "allnumeric" },
- { "data": "pos", width: "7%", sClass: "dt-center mono compact", render: function ( data, type, row ) {return bitvec2window(data) }},
- { "data": "max", render: function ( data, type, row ) {return data.toFixed(3) }},
- { "data": "conorm", render: function ( data, type, row ) {return data.toFixed(3) }},
- { "data": "prob", type: "scientific", render: function ( data, type, row ) {return data.toExponential(3) } },
- { "data": "cprob", type: "scientific", render: function ( data, type, row ) {return data.toExponential(3) } },
- { "data": "overall", type: "scientific", render: function ( data, type, row ) {return data.toExponential(3) } },
- { "data": "word", sClass: "collocator" }
- ],
- "columnDefs": [
- { className: "dt-right", "targets": [0,2,3,4,5,6] },
- { className: "dt-center", "targets": [ 1] },
- { "searchable": false,
- "orderable": false,
- "targets": 0
- },
- { "type": "scientific", targets: [2,3,4,5,6] },
- { "orderSequence": [ "desc" ], "targets": [ 2, 3, 4, 5, 6 ] },
- { "orderSequence": [ "asc", "desc" ], "targets": [ 1, 7 ] },
- ],
- "order": [[ 4, 'desc' ]],
- } );
-
- t.on( 'order.dt search.dt', function () {
- t.column(0, {order:'applied'}).nodes().each( function (cell, i) {
- cell.innerHTML = i+1;
- } );
- } ).draw();
- }
- $("#tabs").css("visibility", "visible"); // now we can show the tabs
+ t.on( 'order.dt search.dt', function () {
+ t.column(0, {order:'applied'}).nodes().each( function (cell, i) {
+ cell.innerHTML = i+1;
+ } );
+ } ).draw();
+ }
+ $("#tabs").css("visibility", "visible"); // now we can show the tabs
});
$(function(){
- $("#dropdownoptions").dialog({
- title: "Options",
- autoOpen: false,
- modal: false,
- draggable: false,
- height: "auto",
- width: "auto",
- resizable: false,
- buttons: {
- "Cancel": function() {
- $( this ).dialog( "close" );
- },
- "Apply": function() {
- window.open($(location).attr('pathname')+'?'+$('form').serialize(), "_self");
- }
- }
- });
- });
-
- $(function(){
- $("#SEARCH").click(function() {
+ $("#dropdownoptions").dialog({
+ title: "Options",
+ autoOpen: false,
+ modal: false,
+ draggable: false,
+ height: "auto",
+ width: "auto",
+ resizable: false,
+ buttons: {
+ "Cancel": function() {
+ $( this ).dialog( "close" );
+ },
+ "Apply": function() {
window.open($(location).attr('pathname')+'?'+$('form').serialize(), "_self");
- });
+ }
+ }
+ });
});
$(function(){
- $("td.collocator").click(function(){
- queryKorAPCII(this.textContent + " /w5 " + urlParams.get('word'));
- });
+ $("#SEARCH").click(function() {
+ window.open($(location).attr('pathname')+'?'+$('form').serialize(), "_self");
+ });
});
-
+
$(function(){
- $("#showoptions").click(function(){
- $("#dropdownoptions").dialog("open");
- var target = $(this);
- $("#dropdownoptions").dialog("widget").position({
- my: 'left bottom',
- at: 'left bottom',
- of: target
- });
+ $("td.collocator").click(function(){
+ queryKorAPCII(this.textContent + " /w5 " + urlParams.get('word'));
+ });
+ });
+
+ $(function(){
+ $("#showoptions").click(function(){
+ $("#dropdownoptions").dialog("open");
+ var target = $(this);
+ $("#dropdownoptions").dialog("widget").position({
+ my: 'left bottom',
+ at: 'left bottom',
+ of: target
});
+ });
});
$( function() {
- $( "#no_iterations" ).spinner({
- spin: function( event, ui ) {
- if ( ui.value < 1000 ) {
- $( this ).spinner( "value", 1000 );
- return false;
- } else if ( ui.value > 10000 ) {
- $( this ).spinner( "value", 10000 );
- return false;
- }
- }
- });
+ $( "#no_iterations" ).spinner({
+ spin: function( event, ui ) {
+ if ( ui.value < 1000 ) {
+ $( this ).spinner( "value", 1000 );
+ return false;
+ } else if ( ui.value > 10000 ) {
+ $( this ).spinner( "value", 10000 );
+ return false;
+ }
+ }
+ });
} );
$( function() {
- $( "#neighbours" ).spinner({
- spin: function( event, ui ) {
- if ( ui.value < 0 ) {
- $( this ).spinner( "value", 0 );
- return false;
- } else if ( ui.value > 200 ) {
- $( this ).spinner( "value", 200 );
- return false;
- }
- }
- });
+ $( "#neighbours" ).spinner({
+ spin: function( event, ui ) {
+ if ( ui.value < 0 ) {
+ $( this ).spinner( "value", 0 );
+ return false;
+ } else if ( ui.value > 200 ) {
+ $( this ).spinner( "value", 200 );
+ return false;
+ }
+ }
+ });
} );
$( function() {
- $( "#cutoff" ).spinner({
- spin: function( event, ui ) {
- if ( ui.value < 100000 ) {
- $( this ).spinner( "value", 100000 );
- return false;
- } else if ( ui.value > 2000000 ) {
- $( this ).spinner( "value", 2000000 );
- return false;
- }
- }
- });
+ $( "#cutoff" ).spinner({
+ spin: function( event, ui ) {
+ if ( ui.value < 100000 ) {
+ $( this ).spinner( "value", 100000 );
+ return false;
+ } else if ( ui.value > 2000000 ) {
+ $( this ).spinner( "value", 2000000 );
+ return false;
+ }
+ }
+ });
} );
var tabactivated = {}
$( function() {
- $( "#tabs" ).tabs().addClass('tabs-min');
+ $( "#tabs" ).tabs().addClass('tabs-min');
} );
$( function() {
- $( ".controlgroup-vertical" ).controlgroup({
- "direction": "vertical"
- });
+ $( ".controlgroup-vertical" ).controlgroup({
+ "direction": "vertical"
+ });
} );
$(function() {
- $( document ).tooltip({
- content: function() {
- return $(this).attr('title');
- }}
- )
+ $( document ).tooltip({
+ content: function() {
+ return $(this).attr('title');
+ }}
+ )
})
</script>
@@ -427,27 +444,27 @@
var labeler;
function applyJitter() {
- svg.selectAll('.tsnet')
- .data(labels)
- .transition()
- .duration(50)
- .attr("transform", function(d, i) {
- T.Y[i][0] = (d.x - mapWidth/2 - tx)/ss/20;
- T.Y[i][1] = (d.y - mapHeight/2 - ty)/ss/20;
- return "translate(" +
- (d.x) + "," +
- (d.y) + ")";
- });
+ svg.selectAll('.tsnet')
+ .data(labels)
+ .transition()
+ .duration(50)
+ .attr("transform", function(d, i) {
+ T.Y[i][0] = (d.x - mapWidth/2 - tx)/ss/20;
+ T.Y[i][1] = (d.y - mapHeight/2 - ty)/ss/20;
+ return "translate(" +
+ (d.x) + "," +
+ (d.y) + ")";
+ });
}
function updateEmbedding() {
- var Y = T.getSolution();
- svg.selectAll('.tsnet')
- .data(data.words)
- .attr("transform", function(d, i) {
- return "translate(" +
- ((Y[i][0]*20*ss + tx) + mapWidth/2) + "," +
- ((Y[i][1]*20*ss + ty) + mapHeight/2) + ")"; });
+ var Y = T.getSolution();
+ svg.selectAll('.tsnet')
+ .data(data.words)
+ .attr("transform", function(d, i) {
+ return "translate(" +
+ ((Y[i][0]*20*ss + tx) + mapWidth/2) + "," +
+ ((Y[i][1]*20*ss + ty) + mapHeight/2) + ")"; });
}
var svg;
@@ -456,58 +473,58 @@
var text;
function drawEmbedding() {
- $("#embed").empty();
- var div = d3.select("#embed");
+ $("#embed").empty();
+ var div = d3.select("#embed");
- // get min and max in each column of Y
- var Y = T.Y;
+ // get min and max in each column of Y
+ var Y = T.Y;
- svg = div.append("svg") // svg is global
- .attr("width", mapWidth)
- .attr("height", mapHeight);
+ svg = div.append("svg") // svg is global
+ .attr("width", mapWidth)
+ .attr("height", mapHeight);
- var g = svg.selectAll(".b")
- .data(data.words)
- .enter().append("g")
- .attr("class", "tsnet");
+ var g = svg.selectAll(".b")
+ .data(data.words)
+ .enter().append("g")
+ .attr("class", "tsnet");
- g.append("a")
- .attr("xlink:href", function(word) {
- return (data.urlprefix+word);})
- .attr("class", function(d, i) {
- var res="";
- if(data.marked[i]) {
- res="marked ";
- }
- if(data.target.indexOf(" "+d+" ") >= 0) {
- return res+"target";
- } else if(data.ranks[i] < data.mergedEnd) {
- return res+"merged";
- } else {
- return res;
- }
- })
- .attr("title", function(d, i) {
- if(data.mergedEnd > 0) {
- if(data.ranks[i] >= data.mergedEnd) {
- return "rank: "+i +" "+"freq. rank: "+(data.ranks[i]).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
- } else {
- return "rank: "+i +" "+"freq. rank: "+data.ranks[i].toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") + " (merged vocab)";
- }
- } else {
- return "rank: "+i +" "+"freq. rank: "+data.ranks[i].toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
- }
- })
- .append("text")
- .attr("text-anchor", "top")
- .attr("font-size", 12)
- .text(function(d) { return d; });
+ g.append("a")
+ .attr("xlink:href", function(word) {
+ return (data.urlprefix+word);})
+ .attr("class", function(d, i) {
+ var res="";
+ if(data.marked[i]) {
+ res="marked ";
+ }
+ if(data.target.indexOf(" "+d+" ") >= 0) {
+ return res+"target";
+ } else if(data.ranks[i] < data.mergedEnd) {
+ return res+"merged";
+ } else {
+ return res;
+ }
+ })
+ .attr("title", function(d, i) {
+ if(data.mergedEnd > 0) {
+ if(data.ranks[i] >= data.mergedEnd) {
+ return "rank: "+i +" "+"freq. rank: "+(data.ranks[i]).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
+ } else {
+ return "rank: "+i +" "+"freq. rank: "+data.ranks[i].toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") + " (merged vocab)";
+ }
+ } else {
+ return "rank: "+i +" "+"freq. rank: "+data.ranks[i].toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
+ }
+ })
+ .append("text")
+ .attr("text-anchor", "top")
+ .attr("font-size", 12)
+ .text(function(d) { return d; });
- var zoomListener = d3.behavior.zoom()
- .scaleExtent([0.1, 10])
- .center([0,0])
- .on("zoom", zoomHandler);
- zoomListener(svg);
+ var zoomListener = d3.behavior.zoom()
+ .scaleExtent([0.1, 10])
+ .center([0,0])
+ .on("zoom", zoomHandler);
+ zoomListener(svg);
}
var tx=0, ty=0;
@@ -515,109 +532,109 @@
var iter_id=-1;
function zoomHandler() {
- tx = d3.event.translate[0];
- ty = d3.event.translate[1];
- ss = d3.event.scale;
- updateEmbedding();
+ tx = d3.event.translate[0];
+ ty = d3.event.translate[1];
+ ss = d3.event.scale;
+ updateEmbedding();
}
var stepnum = 0;
function stopStep() {
- clearInterval(iter_id);
- text = svg.selectAll("text");
+ clearInterval(iter_id);
+ text = svg.selectAll("text");
- // jitter function needs different data and co-ordinate representation
- labels = d3.range(data.words.length).map(function(i) {
- var x = (T.Y[i][0]*20*ss + tx) + mapWidth/2;
- var y = (T.Y[i][1]*20*ss + ty) + mapHeight/2;
- anchor_array.push({x: x, y: y, r: jitterRadius});
- return {
- x: x,
- y: y,
- name: data.words[i]
- };
- });
+ // jitter function needs different data and co-ordinate representation
+ labels = d3.range(data.words.length).map(function(i) {
+ var x = (T.Y[i][0]*20*ss + tx) + mapWidth/2;
+ var y = (T.Y[i][1]*20*ss + ty) + mapHeight/2;
+ anchor_array.push({x: x, y: y, r: jitterRadius});
+ return {
+ x: x,
+ y: y,
+ name: data.words[i]
+ };
+ });
- // get the actual label bounding boxes for the jitter function
- var index = 0;
- text.each(function() {
- labels[index].width = this.getBBox().width;
- labels[index].height = this.getBBox().height;
- index += 1;
- });
+ // get the actual label bounding boxes for the jitter function
+ var index = 0;
+ text.each(function() {
+ labels[index].width = this.getBBox().width;
+ labels[index].height = this.getBBox().height;
+ index += 1;
+ });
- // setTimeout(updateEmbedding, 1);
- // setTimeout(
- labeler = d3.labeler()
- .label(labels)
- .anchor(anchor_array)
- .width(mapWidth)
- .height(mapHeight)
- .update(applyJitter);
- // .start(1000);
+ // setTimeout(updateEmbedding, 1);
+ // setTimeout(
+ labeler = d3.labeler()
+ .label(labels)
+ .anchor(anchor_array)
+ .width(mapWidth)
+ .height(mapHeight)
+ .update(applyJitter);
+ // .start(1000);
- iter_id = setInterval(jitterStep, 1);
+ iter_id = setInterval(jitterStep, 1);
}
var jitter_i=0;
function jitterStep() {
- if(jitter_i++ > 100) {
- clearInterval(iter_id);
- } else {
- labeler.start2(10);
- applyJitter();
- }
+ if(jitter_i++ > 100) {
+ clearInterval(iter_id);
+ } else {
+ labeler.start2(10);
+ applyJitter();
+ }
}
var last_cost=1000;
function step() {
- var i = T.iter;
+ var i = T.iter;
- if(i > <%= $no_iterations %>) {
- stopStep();
+ if(i > <%= $no_iterations %>) {
+ stopStep();
+ } else {
+ var cost = Math.round(T.step() * 100000) / 100000; // do a few steps
+ $("#cost").html("tsne iteration " + i + ", cost: " + cost.toFixed(5));
+ if(i % 250 == 0 && cost >= last_cost) {
+ stopStep();
} else {
- var cost = Math.round(T.step() * 100000) / 100000; // do a few steps
- $("#cost").html("tsne iteration " + i + ", cost: " + cost.toFixed(5));
- if(i % 250 == 0 && cost >= last_cost) {
- stopStep();
- } else {
- last_cost = cost;
- updateEmbedding();
- }
+ last_cost = cost;
+ updateEmbedding();
}
+ }
}
function showMap(j) {
- data=j;
- T.iter=0;
- T.initDataRaw(data.vecs); // init embedding
- drawEmbedding(); // draw initial embedding
+ data=j;
+ T.iter=0;
+ T.initDataRaw(data.vecs); // init embedding
+ drawEmbedding(); // draw initial embedding
- if(iter_id >= 0) {
- clearInterval(iter_id);
- }
- //T.debugGrad();
- iter_id = setInterval(step, 1);
- if(true) { // (<%= $show_som %>) {
- makeSOM(j, <%= $no_iterations %>);
- }
+ if(iter_id >= 0) {
+ clearInterval(iter_id);
+ }
+ //T.debugGrad();
+ iter_id = setInterval(step, 1);
+ if(true) { // (<%= $show_som %>) {
+ makeSOM(j, <%= $no_iterations %>);
+ }
}
var queryword;
function onload() {
- queryword = document.getElementById('word');
+ queryword = document.getElementById('word');
}
function queryKorAP() {
- window.open('http://korap.ids-mannheim.de/kalamar/?q='+queryword.value, 'KorAP');
+ window.open('http://korap.ids-mannheim.de/kalamar/?q='+queryword.value, 'KorAP');
}
function queryKorAPCII(query) {
- window.open('http://korap.ids-mannheim.de/kalamar/?ql=cosmas2&q='+query, 'KorAP');
+ window.open('http://korap.ids-mannheim.de/kalamar/?ql=cosmas2&q='+query, 'KorAP');
}
</script>
</head>
@@ -628,7 +645,7 @@
</div>
<div id="options" class="widget">
<form id="queryform">
- <input id="word" type="text" name="word" placeholder="Word(s) to be searched" value="<%= $word %>"
+ <input id="word" type="text" name="word" placeholder="Word(s) to be searched" value="<%= $word %>"
title="When looking for multiple words use spaces as separators to search around the average vector and | as separator to get the neighbours for each word."/>
<input id="SEARCH" type="button" value="SEARCH">
<input type="button" id="showoptions" name="showoptions" value="Options" />
@@ -731,8 +748,8 @@
% use Mojo::ByteStream 'b';
% my $urlprefix = url_with->query([word=>'']);
$(window).load(function() {
- var vecs = <%= b(Mojo::JSON::to_json($lists->[0])) %>;
- showMap(<%= b(Mojo::JSON::to_json({target => " $word ", mergedEnd=> $mergedEnd, words => \@words, vecs => \@vecs, ranks => \@ranks, marked => \@marked, urlprefix => $urlprefix})); %>);
+ var vecs = <%= b(Mojo::JSON::to_json($lists->[0])) %>;
+ showMap(<%= b(Mojo::JSON::to_json({target => " $word ", mergedEnd=> $mergedEnd, words => \@words, vecs => \@vecs, ranks => \@ranks, marked => \@marked, urlprefix => $urlprefix})); %>);
});
</script>
% } else {
@@ -743,22 +760,22 @@
</div>
<script>
$( function() {
- $( "#not-found-dialog" ).dialog({
- autoOpen: true,
- modal: true,
- draggable: false,
- height: "auto",
- width: "auto",
- resizable: false,
- buttons: {
- "OK": function() {
- $( this ).dialog( "close" );
- },
- "Apply": function() {
- window.open($(location).attr('pathname')+'?'+$('form').serialize(), "_self");
- }
- }
- });
+ $( "#not-found-dialog" ).dialog({
+ autoOpen: true,
+ modal: true,
+ draggable: false,
+ height: "auto",
+ width: "auto",
+ resizable: false,
+ buttons: {
+ "OK": function() {
+ $( this ).dialog( "close" );
+ },
+ "Apply": function() {
+ window.open($(location).attr('pathname')+'?'+$('form').serialize(), "_self");
+ }
+ }
+ });
});
</script>
</div>
@@ -798,20 +815,20 @@
<tr>
<td align="right">
</td>
- <td align="right">
- </td>
- <td align="right">
- </td>
- <td align="right">
- </td>
- <td align="right">
- </td>
- <td align="right">
- </td>
- <td align="right">
- </td>
- <td align="left">
- </td>
+ <td align="right">
+ </td>
+ <td align="right">
+ </td>
+ <td align="right">
+ </td>
+ <td align="right">
+ </td>
+ <td align="right">
+ </td>
+ <td align="right">
+ </td>
+ <td align="left">
+ </td>
</tr>
</tbody>
</table>
diff --git a/w2v-server.pl b/w2v-server.pl
index 605db6c..35b0295 100755
--- a/w2v-server.pl
+++ b/w2v-server.pl
@@ -194,6 +194,7 @@
float activation_sum;
float conorm;
float max_activation;
+ float heat[16];
} collocator;
typedef struct {
@@ -793,6 +794,7 @@
best[b].conorm = 0.0;
best[b].probability = 0.0;
best[b].cprobability = syn_nbs[0]->best[b].cprobability;
+ memset(best[b].heat, 0, sizeof(float) * 16);
}
float best_window_sum[MAX_NEIGHBOURS];
@@ -847,6 +849,8 @@
word_activation_sum += syn_nbs[a]->best[b].activation;
if(syn_nbs[a]->best[b].activation > best[i].max_activation)
best[i].max_activation = syn_nbs[a]->best[b].activation;
+ if(syn_nbs[a]->best[b].cprobability > best[i].heat[wpos])
+ best[i].heat[wpos] = syn_nbs[a]->best[b].cprobability;
}
}
}
@@ -939,9 +943,10 @@
continue;
}
*/
- chosen[i++]=&vocab[c * max_w];
+ chosen[i++]=c;
HV* hash = newHV();
SV* word = newSVpvf(&vocab[best[a].wordi * max_w], 0);
+ AV* heat = newAV();
if(latin_enc == 0) SvUTF8_on(word);
hv_store(hash, "word", strlen("word"), word , 0);
hv_store(hash, "rank", strlen("rank"), newSVuv(best[a].wordi), 0);
@@ -951,6 +956,9 @@
hv_store(hash, "max", strlen("max"), newSVnv(best[a].max_activation), 0); // newSVnv(target_sums[best[a].wordi]), 0);
hv_store(hash, "overall", strlen("overall"), newSVnv(best[a].activation_sum/total_activation), 0); // newSVnv(target_sums[best[a].wordi]), 0);
hv_store(hash, "pos", strlen("pos"), newSVnv(best[a].position), 0);
+ best[a].heat[5]=0;
+ for(i=10; i >= 0; i--) av_push(heat, newSVnv(best[a].heat[i]));
+ hv_store(hash, "heat", strlen("heat"), newRV_noinc((SV*)heat), 0);
av_push(array, newRV_noinc((SV*)hash));
}
hv_store(result, "syntagmatic", strlen("syntagmatic"), newRV_noinc((SV*)array), 0);