Activation FFNet_Categories_to_Activation (FFNet me, Categories thee)
{
	Activation him = NULL; 
	Categories uniq;
	long i, nl, cSize = thy size, hasCategories = 1;
	
	uniq = Categories_selectUniqueItems (thee, 1);
	if (uniq == NULL)  Melder_error1 (L"There is not enough memory to create a Categories."); 
	
	if (my outputCategories == NULL)
	{
		if (my nUnitsInLayer[my nLayers] == uniq -> size)
		{
			my outputCategories = uniq;
			hasCategories = 0;
		}
		else
		{
			(void) Melder_error1 (L"");
			goto end;
		}
	}
	else if (! ( (nl = OrderedOfString_isSubsetOf (uniq, my outputCategories, NULL)) &&
		nl == uniq -> size && my nOutputs >= uniq -> size))
	{
		 (void) Melder_error1 (L"The Categories do not match the categories of the FFNet.");
		goto end;
	}
	
	him = Activation_create (cSize, my nOutputs);
	if (him == NULL) goto end;
	for (i=1; i <= cSize; i++)
	{
		long pos =  OrderedOfString_indexOfItem_c (my outputCategories, OrderedOfString_itemAtIndex_c (thee, i));
		if (pos < 1)
		{
			 (void) Melder_error3 (L"The FFNet doesn't know the category ", OrderedOfString_itemAtIndex_c (thee, i), L" from Categories.");
				goto end;
		}
		his z[i][pos] = 1.0;
	}
	
end:

	if (hasCategories) forget (uniq);
	if (Melder_hasError ()) forget (him);
	
	return him;
}
Esempio n. 2
0
static void updateWidgets (CategoriesEditor me) {   // all buttons except undo & redo
	long size = ( (Categories) my data)->size;
	bool insert = false, insertAtEnd = true, replace = false, remove = false;
	bool moveUp = false, moveDown = false;
	long posCount;
	autoNUMvector<long> posList (GuiList_getSelectedPositions (my list, & posCount), 1);
	if (posList.peek()) {
		long firstPos = posList[1], lastPos = posList[posCount];
		bool contiguous = ( lastPos - firstPos + 1 == posCount );
		moveUp = contiguous && firstPos > 1;
		moveDown = contiguous && lastPos < size;
		my position = firstPos;
		remove = true;
		replace = true;
		//insertAtEnd = false;
		if (posCount == 1) {
			insert = true;
			//if (posList[1] == size) insertAtEnd = true;
			if (size == 1 && ! str32cmp (CategoriesEditor_EMPTYLABEL,
			                           OrderedOfString_itemAtIndex_c ((OrderedOfString) my data, 1))) {
				remove = false;
			}
		}
	}
	GuiThing_setSensitive (my insert,      insert);
	GuiThing_setSensitive (my insertAtEnd, insertAtEnd);
	GuiThing_setSensitive (my replace,     replace);
	GuiThing_setSensitive (my remove,      remove);
	GuiThing_setSensitive (my moveUp,      moveUp);
	GuiThing_setSensitive (my moveDown,    moveDown);
	if (my history) {
		updateUndoAndRedoMenuItems (me);
	}
	notifyNumberOfSelected (me);
}
autoActivation FFNet_Categories_to_Activation (FFNet me, Categories thee) {
	try {
		autoCategories uniq = Categories_selectUniqueItems (thee);

		if (! my outputCategories) {
			Melder_throw (U"The FFNet does not have categories.");
		}
		long nl = OrderedOfString_isSubsetOf (uniq.get(), my outputCategories.get(), 0);
		if (nl == 0) {
			Melder_throw (U"The Categories do not match the categories of the FFNet.");
		}

		autoActivation him = Activation_create (thy size, my nOutputs);
		for (long i = 1; i <= thy size; i ++) {
			const char32 *citem = OrderedOfString_itemAtIndex_c (thee, i);
			long pos = OrderedOfString_indexOfItem_c (my outputCategories.get(), citem);
			if (pos < 1) {
				Melder_throw (U"The FFNet doesn't know the category ", citem, U".");
			}
			his z [i] [pos] = 1.0;
		}
		return him;
	} catch (MelderError) {
		Melder_throw (me, U": no Activation created.");
	}
}
Esempio n. 4
0
static void gui_list_cb_doubleClick (CategoriesEditor me, GuiList_DoubleClickEvent event) {
	Melder_assert (event -> list == my list);

	//  `my position` should just have been updated by the selectionChanged callback.

	long posCount;
	autoNUMvector<long> posList (GuiList_getSelectedPositions (my list, & posCount), 1);
	if (posCount == 1   // often or even usually true when double-clicking?
	    && posList [1] == my position)   // should be true, but we don't crash if it's false
	{
		const char32 *catg = OrderedOfString_itemAtIndex_c ((OrderedOfString) my data, my position);
		if (catg) {   // should be non-null, but we don't crash if not
			GuiText_setString (my text, catg);
		}
	}
}
Esempio n. 5
0
autoTableOfReal Matrix_and_Categories_to_TableOfReal (Matrix me, Categories thee) {
	try {
		if (thy size != my ny) {
			Melder_throw (U"Number of rows and number of categories must be equal.");
		}

		autoTableOfReal him = TableOfReal_create (my ny, my nx);
		TableOfReal_setSequentialColumnLabels (him.peek(), 0, 0, nullptr, 1, 1);

		for (long i = 1; i <= my ny; i ++) {
			his rowLabels [i] = Melder_dup (OrderedOfString_itemAtIndex_c (thee, i));
		}
		for (long i = 1; i <= my ny; i ++) {
			for (long j = 1; j <= my nx; j ++) {
				his data [i] [j] = my z [i] [j];
			}
		}
		return him;
	} catch (MelderError) {
		Melder_throw (U"TableOfReal not created from Matrix & Categories.");
	}
}
Esempio n. 6
0
TableOfReal Matrix_and_Categories_to_TableOfReal (I, Categories thee)
{
	iam (Matrix); TableOfReal him; long i, j;
	
	if (thy size != my ny) return Melder_errorp1 (L"Matrix_and_Categories_to_TableOfReal: "
		"number of rows and number of categories must be equal.");
		
	if (! (him = TableOfReal_create (my ny, my nx)) ||
		! TableOfReal_setSequentialColumnLabels (him, 0, 0, NULL, 1, 1)) goto end;
	
	for (i = 1; i <= my ny; i++)
	{
		if (! (his rowLabels[i] = Melder_wcsdup_e (OrderedOfString_itemAtIndex_c (thee, i)))) goto end;
	}
		
	for (i = 1; i <= my ny; i++)
	{
		for (j = 1; j <= my nx; j++) his data[i][j] = my z[i][j];
	}
	
end:
	if (Melder_hasError()) forget (him);
	return him;
}
Esempio n. 7
0
static void update (CategoriesEditor me, long from, long to, const long *select, long nSelect) {
	long size = ((Categories) my data) -> size;

	if (size == 0) {
		autoSimpleString str = SimpleString_create (CategoriesEditor_EMPTYLABEL);
		Collection_addItem_move ((Categories) my data, str.move());
		update (me, 0, 0, nullptr, 0);
		return;
	}
	if (from == 0 && from == to) {
		from = 1; to = size;
	}
	if (from < 1 || from > size) {
		from = size;
	}
	if (to < 1 || to > size) {
		to = size;
	}
	if (from > to) {
		long ti = from; from = to; to = ti;
	}

	// Begin optimization: add the items from a table instead of separately.
	try {
		autostring32vector table (from, to);
		long itemCount = GuiList_getNumberOfItems (my list);
		for (long i = from; i <= to; i++) {
			char wcindex[20];
			snprintf (wcindex,20, "%5ld ", i);
			table[i] = Melder_dup_f (Melder_cat (Melder_peek8to32 (wcindex), OrderedOfString_itemAtIndex_c ((OrderedOfString) my data, i)));
		}
		if (itemCount > size) { // some items have been removed from Categories?
			for (long j = itemCount; j > size; j --) {
				GuiList_deleteItem (my list, j);
			}
			itemCount = size;
		}
		if (to > itemCount) {
			for (long j = 1; j <= to - itemCount; j ++) {
				GuiList_insertItem (my list, table [itemCount + j], 0);
			}
		}
		if (from <= itemCount) {
			long n = (to < itemCount ? to : itemCount);
			for (long j = from; j <= n; j++) {
				GuiList_replaceItem (my list, table[j], j);
			}
		}
	} catch (MelderError) {
		throw;
	}

	// End of optimization

	// HIGHLIGHT

	GuiList_deselectAllItems (my list);
	if (size == 1) { /* the only item is always selected */
		const char32 *catg = OrderedOfString_itemAtIndex_c ((OrderedOfString) my data, 1);
		GuiList_selectItem (my list, 1);
		updateWidgets (me);   // instead of "notify". BUG?
		GuiText_setString (my text, catg);
	} else if (nSelect > 0) {
		// Select but postpone highlighting

		for (long i = 1; i <= nSelect; i++) {
			GuiList_selectItem (my list, select[i] > size ? size : select[i]);
		}
	}

	// VIEWPORT

	{
		long top = GuiList_getTopPosition (my list), bottom = GuiList_getBottomPosition (my list);
		long visible = bottom - top + 1;
		if (nSelect == 0) {
			top = my position - visible / 2;
		} else if (select[nSelect] < top) {
			// selection above visible area
			top = select[1];
		} else if (select[1] > bottom) {
			// selection below visible area
			top = select[nSelect] - visible + 1;
		} else {
			long deltaTopPos = -1, nUpdate = to - from + 1;
			if ( (from == select[1] && to == select[nSelect]) || // Replace
			        (nUpdate > 2 && nSelect == 1) /* Inserts */) {
				deltaTopPos = 0;
			} else if (nUpdate == nSelect + 1 && select[1] == from + 1) { // down
				deltaTopPos = 1;
			}
			top += deltaTopPos;
		}
		if (top + visible > size) {
			top = size - visible + 1;
		}
		if (top < 1) {
			top = 1;
		}
		GuiList_setTopPosition (my list, top);
	}
}