Skip to content
Commits on Source (9)
*.o
*.a
/*.1
/makefile.defs
/praat
/praat_nogui
/sendpraat
/.pc/
/dwtest/kanweg.FFNet
/dwtest/kanweg.SpeechSynthesizer
/test/fon/kanweg.txt
/test/kar/kanweg.TextGrid
/test/kar/kanweg_abc*.txt
/* EEG.cpp
*
* Copyright (C) 2011-2012,2013,2014,2015,2017 Paul Boersma
* Copyright (C) 2011-2018 Paul Boersma
*
* This code is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -571,6 +571,26 @@ autoEEG EEG_extractChannel (EEG me, const char32 *channelName) {
}
}
autoEEG EEG_extractChannels (EEG me, numvec channelNumbers) {
try {
integer numberOfChannels = channelNumbers.size;
Melder_require (numberOfChannels > 0,
U"The number of channels should be greater than 0.");
autoEEG you = EEG_create (my xmin, my xmax);
your sound = Sound_extractChannels (my sound.get(), channelNumbers);
your numberOfChannels = numberOfChannels;
your channelNames = NUMvector <char32 *> (1, numberOfChannels);
for (integer ichan = 1; ichan <= numberOfChannels; ichan ++) {
integer originalChannelNumber = Melder_iround (channelNumbers [ichan]);
your channelNames [ichan] = Melder_dup (my channelNames [originalChannelNumber]);
}
your textgrid = Data_copy (my textgrid.get());
return you;
} catch (MelderError) {
Melder_throw (me, U": channels not extracted.");
}
}
autoEEG EEGs_concatenate (OrderedOf<structEEG>* me) {
try {
if (my size < 1)
......@@ -636,9 +656,12 @@ void EEG_replaceTextGrid (EEG me, TextGrid textgrid) {
}
}
autoMixingMatrix EEG_to_MixingMatrix (EEG me, integer maxNumberOfIterations, double tol, int method) {
autoMixingMatrix EEG_to_MixingMatrix (EEG me,
double startTime, double endTime, integer numberOfCrossCorrelations, double lagStep,
integer maxNumberOfIterations, double tol, int method)
{
try {
autoCrossCorrelationTableList tables = Sound_to_CrossCorrelationTableList (my sound.get(), 0.0, 0.0, 0.002, 1);
autoCrossCorrelationTableList tables = Sound_to_CrossCorrelationTableList (my sound.get(), startTime, endTime, numberOfCrossCorrelations, lagStep);
autoMixingMatrix thee = MixingMatrix_create (my sound -> ny, my sound -> ny);
MixingMatrix_setRandomGauss (thee.get(), 0.0, 1.0);
for (integer ichan = 1; ichan <= my numberOfChannels; ichan ++) {
......@@ -652,4 +675,48 @@ autoMixingMatrix EEG_to_MixingMatrix (EEG me, integer maxNumberOfIterations, dou
}
}
autoEEG EEG_MixingMatrix_to_EEG_unmix (EEG me, MixingMatrix you) {
Melder_require (my numberOfChannels == your numberOfRows,
U"To be able to unmix, the number of channels in ", me, U" (", my numberOfChannels, U")",
U" should be equal to the number of rows in ", you, U"(", your numberOfRows, U").");
for (integer ichan = 1; ichan <= your numberOfRows; ichan ++) {
Melder_require (Melder_equ (my channelNames [ichan], your rowLabels [ichan]),
U"To be able to unmix, the name of channel ", ichan,
U" should be the same in ", me, U" (where it is ", my channelNames [ichan], U")",
U" as in ", you, U" (where it is ", your rowLabels [ichan], U").");
}
autoEEG him = EEG_create (my xmin, my xmax);
his sound = Sound_MixingMatrix_unmix (my sound.get(), you);
his textgrid = Data_copy (my textgrid.get());
his numberOfChannels = your numberOfColumns;
his channelNames = NUMvector <char32 *> (1, his numberOfChannels);
//his channelNames = NUMstrings_copy (your columnLabels, 1, his numberOfChannels);
for (integer ichan = 1; ichan <= his numberOfChannels; ichan ++) {
his channelNames [ichan] = Melder_dup (your columnLabels [ichan]);
}
return him;
}
autoEEG EEG_MixingMatrix_to_EEG_mix (EEG me, MixingMatrix you) {
Melder_require (my numberOfChannels == your numberOfColumns,
U"To be able to mix, the number of channels in ", me, U" (", my numberOfChannels, U")",
U" should be equal to the number of columns in ", you, U"(", your numberOfColumns, U").");
for (integer ichan = 1; ichan <= your numberOfColumns; ichan ++) {
Melder_require (Melder_equ (my channelNames [ichan], your columnLabels [ichan]),
U"To be able to mix, the name of channel ", ichan,
U" should be the same in ", me, U" (where it is ", my channelNames [ichan], U")",
U" as in ", you, U" (where it is ", your columnLabels [ichan], U").");
}
autoEEG him = EEG_create (my xmin, my xmax);
his sound = Sound_MixingMatrix_mix (my sound.get(), you);
his textgrid = Data_copy (my textgrid.get());
his numberOfChannels = your numberOfRows;
his channelNames = NUMvector <char32 *> (1, his numberOfChannels);
//his channelNames = NUMstrings_copy (your rowLabels, 1, his numberOfChannels);
for (integer ichan = 1; ichan <= his numberOfChannels; ichan ++) {
his channelNames [ichan] = Melder_dup (your rowLabels [ichan]);
}
return him;
}
/* End of file EEG.cpp */
......@@ -2,7 +2,7 @@
#define _EEG_h_
/* EEG.h
*
* Copyright (C) 2011-2012,2014,2015,2017 Paul Boersma
* Copyright (C) 2011-2012,2014,2015,2017,2018 Paul Boersma
*
* This code is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -53,11 +53,18 @@ void EEG_setChannelToZero (EEG me, const char32 *channelName);
void EEG_removeTriggers (EEG me, kMelder_string which, const char32 *criterion);
autoEEG EEG_extractChannel (EEG me, integer channelNumber);
autoEEG EEG_extractChannel (EEG me, const char32 *channelName);
autoEEG EEG_extractChannels (EEG me, numvec channelNumbers);
static inline autoSound EEG_extractSound (EEG me) { return Data_copy (my sound.get()); }
static inline autoTextGrid EEG_extractTextGrid (EEG me) { return Data_copy (my textgrid.get()); }
autoEEG EEG_extractPart (EEG me, double tmin, double tmax, bool preserveTimes);
void EEG_replaceTextGrid (EEG me, TextGrid textgrid);
autoMixingMatrix EEG_to_MixingMatrix (EEG me, integer maxNumberOfIterations, double tol, int method);
autoMixingMatrix EEG_to_MixingMatrix (EEG me,
double startTime, double endTime, integer numberOfCrossCorrelations, double lagStep,
integer maxNumberOfIterations, double tol, int method);
autoEEG EEG_MixingMatrix_to_EEG_unmix (EEG me, MixingMatrix you);
autoEEG EEG_MixingMatrix_to_EEG_mix (EEG me, MixingMatrix you);
/* End of file EEG.h */
#endif
......@@ -21,7 +21,7 @@
void manual_EEG_init (ManPages me);
void manual_EEG_init (ManPages me) {
MAN_BEGIN (U"EEG", U"ppgb", 20120511)
MAN_BEGIN (U"EEG", U"ppgb", 20180329)
INTRO (U"EEG means electro-encephalography: brain potentials recorded via e.g. 32 or 64 electrodes on the scalp. "
"In Praat, an EEG object looks like a combination of a Sound object with e.g. 32 or 64 channels "
"and a TextGrid object that marks the events.")
......@@ -86,6 +86,27 @@ NORMAL (U"Once you have an ERPTier, you can extract each of the 150 ERPs from it
NORMAL (U"Once you have an ERP object, you can look into it with ##View & Edit#. "
"If you want to see in the ERP window the scalp distribution at the time of the cursor, or the average scalp distribution in the selected time stretch, "
"you have to switch on ##Show selection viewer# in the #Preferences window (available from the #File menu).")
ENTRY (U"See also")
LIST_ITEM (U"\\bu @@Independent Component Analysis on EEG@")
MAN_END
MAN_BEGIN (U"Independent Component Analysis on EEG", U"ppgb", 20180329)
INTRO (U"Independent Component Analysis (ICA) is often used to improve @EEG signals. "
"See @@blind source separation@ for the algorithm.")
ENTRY (U"1. Selecting your channels")
NORMAL (U"You typically will not want to do ICA on all 80 channels of your signal, "
"some of which may not even be EEG channels. To create a smaller EEG with e.g. only the 64 scalp channels, "
"use ##EEG: Extract channels...#. From here on we will assume that your reduced EEG has 64 channels.")
ENTRY (U"2. How to get a MixingMatrix")
NORMAL (U"Once you have your reduced EEG, you can start to do ICA on it. "
"This starts by creating a @MixingMatrix: select your EEG object and choose ##To MixingMatrix...#. "
"The resulting MixingMatrix has one row for each of your 64 EEG channels, and columns called \"ic1\" through \"ic64\".")
ENTRY (U"3. How to see the independent components")
NORMAL (U"Select you EEG and your MixingMatrix together and choose ##Unmix#. "
"The resulting ICA-EEG will have 64 channels called \"ic1\" through \"ic64\".")
ENTRY (U"4. Just checking back")
NORMAL (U"If you select your ICA-EEG together with your MixingMatrix choose ##Mix#, "
"the resulting EEG should be very similar to your original 64-channel EEG.")
MAN_END
}
......
/* praat_EEG.cpp
*
* Copyright (C) 2011-2012,2013,2014,2015,2016,2017 Paul Boersma
* Copyright (C) 2011-2018 Paul Boersma
*
* This code is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -198,6 +198,15 @@ DO
CONVERT_EACH_END (my name, U"_", channelName)
}
FORM (NEW_EEG_extractChannels, U"EEG: Extract channels", nullptr) {
NUMVEC (channels, U"Channel numbers", U"to# (64)")
OK
DO
CONVERT_EACH (EEG)
autoEEG result = EEG_extractChannels (me, channels);
CONVERT_EACH_END (my name, U"_ch")
}
FORM (NEW_EEG_extractPart, U"EEG: Extract part", nullptr) {
REAL (fromTime, U"left Time range (s)", U"0.0")
REAL (toTime, U"right Time range (s)", U"1.0")
......@@ -281,6 +290,9 @@ DIRECT (NEW1_EEGs_concatenate) {
}
FORM (NEW_EEG_to_MixingMatrix, U"To MixingMatrix", nullptr) {
praat_TimeFunction_RANGE (startTime, endTime)
NATURAL (numberOfCrossCorrelations, U"Number of cross-correlations", U"40")
POSITIVE (lagStep, U"Lag step (s)", U"0.002")
NATURAL (maximumNumberOfIterations, U"Maximum number of iterations", U"100")
POSITIVE (tolerance, U"Tolerance", U"0.001")
OPTIONMENUx (diagonalizationMethod, U"Diagonalization method", 2, 1)
......@@ -290,10 +302,23 @@ FORM (NEW_EEG_to_MixingMatrix, U"To MixingMatrix", nullptr) {
DO
CONVERT_EACH (EEG)
autoMixingMatrix result = EEG_to_MixingMatrix (me,
startTime, endTime, numberOfCrossCorrelations, lagStep,
maximumNumberOfIterations, tolerance, diagonalizationMethod);
CONVERT_EACH_END (my name)
}
DIRECT (NEW_EEG_MixingMatrix_to_EEG_unmix) {
CONVERT_TWO (EEG, MixingMatrix)
autoEEG result = EEG_MixingMatrix_to_EEG_unmix (me, you);
CONVERT_TWO_END (my name, U"_", your name)
}
DIRECT (NEW_EEG_MixingMatrix_to_EEG_mix) {
CONVERT_TWO (EEG, MixingMatrix)
autoEEG result = EEG_MixingMatrix_to_EEG_mix (me, you);
CONVERT_TWO_END (my name, U"_", your name)
}
// MARK: - EEG & TextGrid
DIRECT (MODIFY_EEG_TextGrid_replaceTextGrid) {
......@@ -730,6 +755,7 @@ void praat_EEG_init () {
praat_addAction1 (classEEG, 0, U"Set channel to zero...", nullptr, 1, MODIFY_EEG_setChannelToZero);
praat_addAction1 (classEEG, 0, U"Analyse", nullptr, 0, nullptr);
praat_addAction1 (classEEG, 0, U"Extract channel...", nullptr, 0, NEW_EEG_extractChannel);
praat_addAction1 (classEEG, 0, U"Extract channels...", nullptr, 0, NEW_EEG_extractChannels);
praat_addAction1 (classEEG, 0, U"Extract part...", nullptr, 0, NEW_EEG_extractPart);
praat_addAction1 (classEEG, 0, U"To ERPTier -", nullptr, 0, nullptr);
praat_addAction1 (classEEG, 0, U"To ERPTier (bit)...", nullptr, 1, NEW_EEG_to_ERPTier_bit);
......@@ -790,6 +816,8 @@ void praat_EEG_init () {
praat_addAction1 (classERPTier, 0, U"Extract ERP...", nullptr, 0, NEW_ERPTier_to_ERP);
praat_addAction1 (classERPTier, 0, U"To ERP (mean)", nullptr, 0, NEW_ERPTier_to_ERP_mean);
praat_addAction2 (classEEG, 1, classMixingMatrix, 1, U"To EEG (unmix)", nullptr, 0, NEW_EEG_MixingMatrix_to_EEG_unmix);
praat_addAction2 (classEEG, 1, classMixingMatrix, 1, U"To EEG (mix)", nullptr, 0, NEW_EEG_MixingMatrix_to_EEG_mix);
praat_addAction2 (classEEG, 1, classTextGrid, 1, U"Replace TextGrid", nullptr, 0, MODIFY_EEG_TextGrid_replaceTextGrid);
praat_addAction2 (classERPTier, 1, classTable, 1, U"Extract -", nullptr, 0, nullptr);
praat_addAction2 (classERPTier, 1, classTable, 1, U"Extract events where column (number)...", nullptr, 1, NEW1_ERPTier_Table_extractEventsWhereColumn_number);
......
......@@ -81,10 +81,10 @@ autoActivationList FFNet_Categories_to_ActivationList (FFNet me, Categories thee
autoActivationList him = ActivationList_create (thy size, my nOutputs);
for (integer i = 1; i <= thy size; i ++) {
const char32 *citem = OrderedOfString_itemAtIndex_c (thee, i);
integer pos = OrderedOfString_indexOfItem_c (my outputCategories.get(), citem);
SimpleString category = thy at [i];
integer pos = OrderedOfString_indexOfItem_c (my outputCategories.get(), category -> string);
if (pos < 1) {
Melder_throw (U"The FFNet doesn't know the category ", citem, U".");
Melder_throw (U"The FFNet doesn't know the category ", category -> string, U".");
}
his z [i] [pos] = 1.0;
}
......
/* Art_Speaker.cpp
*
* Copyright (C) 1992-2009,2011,2012,2014-2017 Paul Boersma
* Copyright (C) 1992-2009,2011,2012,2014-2018 Paul Boersma
*
* This code is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -50,51 +50,51 @@ void Art_Speaker_toVocalTract (Art _art, Speaker speaker,
/* does not follow completely the horizontal movements. */
/* Anterior larynx. */
intX [1] = -14 * f + 0.5 * hyoid.dx; intY [1] = -53 * f + hyoid.dy;
intX [1] = -14.0 * f + 0.5 * hyoid.dx; intY [1] = -53.0 * f + hyoid.dy;
/* Top of larynx. */
intX [2] = -20 * f + hyoid.dx; intY [2] = -33 * f + hyoid.dy;
intX [2] = -20.0 * f + hyoid.dx; intY [2] = -33.0 * f + hyoid.dy;
/* Epiglottis. */
intX [3] = -20 * f + hyoid.dx; intY [3] = -26 * f + hyoid.dy;
intX [3] = -20.0 * f + hyoid.dx; intY [3] = -26.0 * f + hyoid.dy;
/* Hyoid bone. */
intX [4] = -16 * f + hyoid.dx; intY [4] = -26 * f + hyoid.dy;
intX [4] = -16.0 * f + hyoid.dx; intY [4] = -26.0 * f + hyoid.dy;
/* Posterior larynx. */
extX [1] = -22 * f + hyoid.dx; extY [1] = -53 * f + hyoid.dy;
extX [1] = -22.0 * f + hyoid.dx; extY [1] = -53.0 * f + hyoid.dy;
/* Esophagus. */
extX [2] = -26 * f + hyoid.dx; extY [2] = -40 * f + hyoid.dy;
extX [2] = -26.0 * f + hyoid.dx; extY [2] = -40.0 * f + hyoid.dy;
/* The lower pharynx moves up and down with the hyoid bone. */
/* The lower constrictor muscle pulls the rear pharyngeal wall forwards. */
extX [3] = -34 * f + art [(int) kArt_muscle::SPHINCTER] * 5 * f; extY [3] = extY [2];
extX [3] = -34.0 * f + art [(int) kArt_muscle::SPHINCTER] * (5.0 * f);
extY [3] = extY [2];
/* The upper pharynx is fixed at the height of the velum. */
/* The upper constrictor muscle pulls the rear pharyngeal wall forwards. */
extX [5] = -34 * f + art [(int) kArt_muscle::SPHINCTER] * 5 * f;
extX [5] = -34.0 * f + art [(int) kArt_muscle::SPHINCTER] * (5.0 * f);
extY [5] = speaker -> velum.y;
/* The height of the middle pharynx is in between the lower and upper pharynx. */
/* The middle constrictor muscle pulls the rear pharyngeal wall forwards. */
extX [4] = -34 * f + art [(int) kArt_muscle::SPHINCTER] * 5 * f;
extX [4] = -34.0 * f + art [(int) kArt_muscle::SPHINCTER] * (5.0 * f);
extY [4] = 0.5 * (extY [3] + extY [5]);
/* Tongue root. */
jaw.x = -75 * f, jaw.y = 53 * f; /* Position of the condyle. */
jaw.x = -75.0 * f, jaw.y = 53.0 * f; // position of the condyle
jaw.da = art [(int) kArt_muscle::MASSETER] * 0.15
- art [(int) kArt_muscle::MYLOHYOID] * 0.20;
body.x = jaw.x + 81 * f * cos (-0.60 + jaw.da)
- art [(int) kArt_muscle::STYLOGLOSSUS] * 10 * f
+ art [(int) kArt_muscle::GENIOGLOSSUS] * 10 * f;
body.y = jaw.y + 81 * f * sin (-0.60 + jaw.da)
- art [(int) kArt_muscle::HYOGLOSSUS] * 10 * f
+ art [(int) kArt_muscle::STYLOGLOSSUS] * 5 * f;
body.x = jaw.x + 81.0 * f * cos (-0.60 + jaw.da)
- art [(int) kArt_muscle::STYLOGLOSSUS] * (10.0 * f)
+ art [(int) kArt_muscle::GENIOGLOSSUS] * (10.0 * f);
body.y = jaw.y + 81.0 * f * sin (-0.60 + jaw.da)
- art [(int) kArt_muscle::HYOGLOSSUS] * (10.0 * f)
+ art [(int) kArt_muscle::STYLOGLOSSUS] * (5.0 * f);
*bodyX = body.x;
*bodyY = body.y;
body.r = sqrt ((jaw.x - body.x) * (jaw.x - body.x)
+ (jaw.y - body.y) * (jaw.y - body.y));
body.radius = 20 * f;
body.r = sqrt ((jaw.x - body.x) * (jaw.x - body.x) + (jaw.y - body.y) * (jaw.y - body.y));
body.radius = 20.0 * f;
HBody_x = body.x - intX [4];
HBody_y = body.y - intY [4];
HC = sqrt (HBody_x * HBody_x + HBody_y * HBody_y);
......@@ -191,7 +191,6 @@ void Art_Speaker_draw (Art art, Speaker speaker, Graphics g) {
double f = speaker -> relativeSize * 1e-3;
double intX [1 + 16], intY [1 + 16], extX [1 + 11], extY [1 + 11];
double bodyX, bodyY;
int i;
Graphics_Viewport previous;
Art_Speaker_toVocalTract (art, speaker, intX, intY, extX, extY, & bodyX, & bodyY);
......@@ -200,22 +199,22 @@ void Art_Speaker_draw (Art art, Speaker speaker, Graphics g) {
/* Draw inner contour. */
for (i = 1; i <= 5; i ++)
for (integer i = 1; i <= 5; i ++)
Graphics_line (g, intX [i], intY [i], intX [i + 1], intY [i + 1]);
Graphics_arc (g, bodyX, bodyY, 20 * f,
atan2 (intY [7] - bodyY, intX [7] - bodyX) * 180 / NUMpi,
atan2 (intY [6] - bodyY, intX [6] - bodyX) * 180 / NUMpi);
for (i = 7; i <= 15; i ++)
Graphics_arc (g, bodyX, bodyY, 20.0 * f,
atan2 (intY [7] - bodyY, intX [7] - bodyX) * (180.0 / NUMpi),
atan2 (intY [6] - bodyY, intX [6] - bodyX) * (180.0 / NUMpi));
for (integer i = 7; i <= 15; i ++)
Graphics_line (g, intX [i], intY [i], intX [i + 1], intY [i + 1]);
/* Draw outer contour. */
for (i = 1; i <= 5; i ++)
for (integer i = 1; i <= 5; i ++)
Graphics_line (g, extX [i], extY [i], extX [i + 1], extY [i + 1]);
Graphics_arc (g, 0, 0, speaker -> palate.radius,
speaker -> alveoli.a * 180 / NUMpi,
speaker -> velum.a * 180 / NUMpi);
for (i = 7; i <= 10; i ++)
Graphics_arc (g, 0.0, 0.0, speaker -> palate.radius,
speaker -> alveoli.a * (180.0 / NUMpi),
speaker -> velum.a * (180.0 / NUMpi));
for (integer i = 7; i <= 10; i ++)
Graphics_line (g, extX [i], extY [i], extX [i + 1], extY [i + 1]);
Graphics_resetViewport (g, previous);
}
......@@ -225,32 +224,34 @@ void Art_Speaker_fillInnerContour (Art art, Speaker speaker, Graphics g) {
double intX [1 + 16], intY [1 + 16], extX [1 + 11], extY [1 + 11];
double x [1 + 16], y [1 + 16];
double bodyX, bodyY;
int i;
Graphics_Viewport previous;
Art_Speaker_toVocalTract (art, speaker, intX, intY, extX, extY, & bodyX, & bodyY);
previous = Graphics_insetViewport (g, 0.1, 0.9, 0.1, 0.9);
Graphics_setWindow (g, -0.05, 0.05, -0.05, 0.05);
for (i = 1; i <= 16; i ++) { x [i] = intX [i]; y [i] = intY [i]; }
for (integer i = 1; i <= 16; i ++) {
x [i] = intX [i];
y [i] = intY [i];
}
Graphics_setGrey (g, 0.8);
Graphics_fillArea (g, 16, & x [1], & y [1]);
Graphics_fillCircle (g, bodyX, bodyY, 20 * f);
Graphics_fillCircle (g, bodyX, bodyY, 20.0 * f);
Graphics_setGrey (g, 0.0);
Graphics_resetViewport (g, previous);
}
static double arcLength (double from, double to) {
double result = to - from;
while (result > 0.0) result -= 2 * NUMpi;
while (result < 0.0) result += 2 * NUMpi;
while (result > 0.0) result -= 2.0 * NUMpi;
while (result < 0.0) result += 2.0 * NUMpi;
return result;
}
static int Art_Speaker_meshCount = 27;
static double bodyX, bodyY, bodyRadius;
static double toLine (double x, double y, const double intX [], const double intY [], int i) {
int nearby;
static double toLine (double x, double y, const double intX [], const double intY [], integer i) {
integer nearby;
if (i == 6) {
double a7 = atan2 (intY [7] - bodyY, intX [7] - bodyX);
double a6 = atan2 (intY [6] - bodyY, intX [6] - bodyX);
......@@ -280,8 +281,8 @@ static double toLine (double x, double y, const double intX [], const double int
static int inside (double x, double y,
const double intX [], const double intY [])
{
int i, up = 0;
for (i = 1; i <= 16 - 1; i ++)
integer up = 0;
for (integer i = 1; i <= 16 - 1; i ++)
if ((y > intY [i]) != (y > intY [i + 1])) {
double slope = (intX [i + 1] - intX [i]) / (intY [i + 1] - intY [i]);
if (x > intX [i] + (y - intY [i]) * slope)
......@@ -293,23 +294,22 @@ static int inside (double x, double y,
void Art_Speaker_meshVocalTract (Art art, Speaker speaker,
double xi [], double yi [], double xe [], double ye [],
double xmm [], double ymm [], int closed [])
double xmm [], double ymm [], bool closed [])
{
double f = speaker -> relativeSize * 1e-3;
double intX [1 + 16], intY [1 + 16], extX [1 + 11], extY [1 + 11], d_angle;
double xm [40], ym [40];
int i;
Art_Speaker_toVocalTract (art, speaker, intX, intY, extX, extY, & bodyX, & bodyY);
bodyRadius = 20 * f;
bodyRadius = 20.0 * f;
xe [1] = extX [1]; /* Eq. 5.45 */
xe [1] = extX [1]; // eq. 5.45
ye [1] = extY [1];
xe [2] = 0.2 * extX [2] + 0.8 * extX [1];
ye [2] = 0.2 * extY [2] + 0.8 * extY [1];
xe [3] = 0.6 * extX [2] + 0.4 * extX [1];
ye [3] = 0.6 * extY [2] + 0.4 * extY [1];
xe [4] = 0.9 * extX [3] + 0.1 * extX [4]; /* Eq. 5.46 */
xe [4] = 0.9 * extX [3] + 0.1 * extX [4]; // eq. 5.46
ye [4] = 0.9 * extY [3] + 0.1 * extY [4];
xe [5] = 0.7 * extX [3] + 0.3 * extX [4];
ye [5] = 0.7 * extY [3] + 0.3 * extY [4];
......@@ -329,8 +329,8 @@ void Art_Speaker_meshVocalTract (Art art, Speaker speaker,
ye [12] = 0.3 * extY [4] + 0.7 * extY [5];
xe [13] = 0.1 * extX [4] + 0.9 * extX [5];
ye [13] = 0.1 * extY [4] + 0.9 * extY [5];
d_angle = (atan2 (ye [13], xe [13]) - 0.5 * NUMpi) / 6; /* Eq. 5.47 */
for (i = 14; i <= 18; i ++) {
d_angle = (atan2 (ye [13], xe [13]) - 0.5 * NUMpi) / 6; // eq. 5.47
for (integer i = 14; i <= 18; i ++) {
double a = 0.5 * NUMpi + (19 - i) * d_angle;
xe [i] = speaker -> palate.radius * cos (a);
ye [i] = speaker -> palate.radius * sin (a);
......@@ -340,7 +340,7 @@ void Art_Speaker_meshVocalTract (Art art, Speaker speaker,
xe [20] = 0.25 * extX [7];
xe [21] = 0.50 * extX [7];
xe [22] = 0.75 * extX [7];
for (i = 20; i <= 22; i ++) {
for (integer i = 20; i <= 22; i ++) {
ye [i] = speaker -> palate.radius * sqrt (1.0 - xe [i] * xe [i] /
(speaker -> palate.radius * speaker -> palate.radius));
}
......@@ -354,69 +354,66 @@ void Art_Speaker_meshVocalTract (Art art, Speaker speaker,
xe [27] = 0.75 * extX [11] + 0.25 * extX [9];
ye [26] = extY [10];
ye [27] = 0.5 * (extY [10] + extY [11]);
for (i = 1; i <= 27; i ++) { /* Every mesh point. */
double minimum = 100000;
int j;
for (j = 1; j <= 15 - 1; j ++) { /* Every internal segment. */
for (integer i = 1; i <= 27; i ++) { // every mesh point
double minimum = 100000.0;
for (integer j = 1; j <= 15 - 1; j ++) { // every internal segment
double d = toLine (xe [i], ye [i], intX, intY, j);
if (d < minimum) minimum = d;
}
if ((closed [i] = inside (xe [i], ye [i], intX, intY)) != 0)
if (( closed [i] = inside (xe [i], ye [i], intX, intY) ))
minimum = - minimum;
if (xe [i] >= 0.0) { /* Vertical line pieces. */
if (xe [i] >= 0.0) { // vertical line pieces
xi [i] = xe [i];
yi [i] = ye [i] - minimum;
} else if (ye [i] <= 0.0) { /* Horizontal line pieces. */
} else if (ye [i] <= 0.0) { // horizontal line pieces
xi [i] = xe [i] + minimum;
yi [i] = ye [i];
} else { /* Radial line pieces, centre = centre of palate arc. */
} else { // radial line pieces, centre = centre of palate arc
double angle = atan2 (ye [i], xe [i]);
xi [i] = xe [i] - minimum * cos (angle);
yi [i] = ye [i] - minimum * sin (angle);
}
}
for (i = 1; i <= Art_Speaker_meshCount; i ++) {
for (integer i = 1; i <= Art_Speaker_meshCount; i ++) {
xm [i] = 0.5 * (xe [i] + xi [i]);
ym [i] = 0.5 * (ye [i] + yi [i]);
}
for (i = 2; i <= Art_Speaker_meshCount; i ++) {
for (integer i = 2; i <= Art_Speaker_meshCount; i ++) {
xmm [i] = 0.5 * (xm [i - 1] + xm [i]);
ymm [i] = 0.5 * (ym [i - 1] + ym [i]);
}
xmm [1] = 2 * xm [1] - xmm [2];
ymm [1] = 2 * ym [1] - ymm [2];
xmm [Art_Speaker_meshCount + 1] = 2 * xm [Art_Speaker_meshCount]
xmm [1] = 2.0 * xm [1] - xmm [2];
ymm [1] = 2.0 * ym [1] - ymm [2];
xmm [Art_Speaker_meshCount + 1] = 2.0 * xm [Art_Speaker_meshCount]
- xmm [Art_Speaker_meshCount];
ymm [Art_Speaker_meshCount + 1] = 2 * ym [Art_Speaker_meshCount]
ymm [Art_Speaker_meshCount + 1] = 2.0 * ym [Art_Speaker_meshCount]
- ymm [Art_Speaker_meshCount];
}
void Art_Speaker_drawMesh (Art art, Speaker speaker, Graphics graphics) {
double xi [40], yi [40], xe [40], ye [40], xmm [40], ymm [40];
int closed [40];
int i;
Graphics_Viewport previous;
bool closed [40];
int oldLineType = Graphics_inqLineType (graphics);
Art_Speaker_meshVocalTract (art, speaker, xi, yi, xe, ye, xmm, ymm, closed);
previous = Graphics_insetViewport (graphics, 0.1, 0.9, 0.1, 0.9); /* Must be square. */
Graphics_Viewport previous = Graphics_insetViewport (graphics, 0.1, 0.9, 0.1, 0.9); // must be square
Graphics_setWindow (graphics, -0.05, 0.05, -0.05, 0.05);
/* Mesh lines. */
for (i = 1; i <= Art_Speaker_meshCount; i ++)
for (integer i = 1; i <= Art_Speaker_meshCount; i ++)
Graphics_line (graphics, xi [i], yi [i], xe [i], ye [i]);
/* Radii. */
Graphics_setLineType (graphics, Graphics_DOTTED);
for (i = 1; i <= Art_Speaker_meshCount; i ++)
for (integer i = 1; i <= Art_Speaker_meshCount; i ++)
if (xe [i] <= 0.0 && ye [i] >= 0.0)
Graphics_line (graphics, 0.0, 0.0, 0.9 * xi [i], 0.9 * yi [i]);
Graphics_setLineType (graphics, oldLineType);
/* Lengths. */
for (i = 1; i <= Art_Speaker_meshCount; i ++)
for (integer i = 1; i <= Art_Speaker_meshCount; i ++)
Graphics_line (graphics, xmm [i], ymm [i], xmm [i + 1], ymm [i + 1]);
for (i = 1; i <= Art_Speaker_meshCount + 1; i ++)
for (integer i = 1; i <= Art_Speaker_meshCount + 1; i ++)
Graphics_speckle (graphics, xmm [i], ymm [i]);
Graphics_setTextAlignment (graphics, Graphics_LEFT, Graphics_HALF);
Graphics_text (graphics, 0.0, 0.0, U"O"); // origin
......
/* Art_Speaker.h
*
* Copyright (C) 1992-2005,2011,2016,2017 Paul Boersma
* Copyright (C) 1992-2005,2011,2016-2018 Paul Boersma
*
* This code is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -45,7 +45,7 @@ void Art_Speaker_fillInnerContour (Art art, Speaker speaker, Graphics g);
void Art_Speaker_meshVocalTract (Art art, Speaker speaker,
double xi [], double yi [], double xe [], double ye [],
double xmm [], double ymm [], int closed []);
double xmm [], double ymm [], bool closed []);
void Art_Speaker_drawMesh (Art art, Speaker speaker, Graphics g);
......
/* Art_Speaker_Delta.cpp
*
* Copyright (C) 1992-2005,2009,2011,2016,2017 Paul Boersma
* Copyright (C) 1992-2005,2009,2011,2016-2018 Paul Boersma
*
* This code is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -23,12 +23,10 @@ void Art_Speaker_intoDelta (Art art, Speaker speaker, Delta delta)
{
double f = speaker -> relativeSize * 1e-3;
double xe [30], ye [30], xi [30], yi [30], xmm [30], ymm [30], dx, dy;
int closed [40];
int itube;
/* Lungs. */
for (itube = 7; itube <= 18; itube ++)
for (integer itube = 7; itube <= 18; itube ++)
delta -> tube [itube]. Dyeq = 120 * f * (1 + art -> art [(int) kArt_muscle::LUNGS]);
/* Glottis. */
......@@ -37,7 +35,7 @@ void Art_Speaker_intoDelta (Art art, Speaker speaker, Delta delta)
Delta_Tube t = delta -> tube + 36;
t -> Dyeq = f * (5 - 10 * art -> art [(int) kArt_muscle::INTERARYTENOID]
+ 3 * art -> art [(int) kArt_muscle::POSTERIOR_CRICOARYTENOID]
- 3 * art -> art [(int) kArt_muscle::LATERAL_CRICOARYTENOID]); /* 4.38 */
- 3 * art -> art [(int) kArt_muscle::LATERAL_CRICOARYTENOID]); // 4.38
t -> k1 = speaker -> lowerCord.k1 * (1 + art -> art [(int) kArt_muscle::CRICOTHYROID]);
t -> k3 = t -> k1 * (20 / t -> Dz) * (20 / t -> Dz);
}
......@@ -54,17 +52,18 @@ void Art_Speaker_intoDelta (Art art, Speaker speaker, Delta delta)
delta -> tube [84]. k1 = 0.75 * 160 + 0.25 * delta -> tube [36]. k1;
delta -> tube [85]. k1 = 0.50 * 160 + 0.50 * delta -> tube [36]. k1;
delta -> tube [86]. k1 = 0.25 * 160 + 0.75 * delta -> tube [36]. k1;
for (itube = 84; itube <= 86; itube ++)
for (integer itube = 84; itube <= 86; itube ++)
delta -> tube [itube]. k3 = delta -> tube [itube]. k1 *
(20 / delta -> tube [itube]. Dz) * (20 / delta -> tube [itube]. Dz);
}
/* Vocal tract. */
bool closed [40];
Art_Speaker_meshVocalTract (art, speaker, xi, yi, xe, ye, xmm, ymm, closed);
for (itube = 38; itube <= 64; itube ++) {
for (integer itube = 38; itube <= 64; itube ++) {
Delta_Tube t = delta -> tube + itube;
int i = itube - 37;
integer i = itube - 37;
t -> Dxeq = sqrt (( dx = xmm [i] - xmm [i + 1], dx * dx ) + ( dy = ymm [i] - ymm [i + 1], dy * dy ));
t -> Dyeq = sqrt (( dx = xe [i] - xi [i], dx * dx ) + ( dy = ye [i] - yi [i], dy * dy ));
if (closed [i]) t -> Dyeq = - t -> Dyeq;
......@@ -74,9 +73,9 @@ void Art_Speaker_intoDelta (Art art, Speaker speaker, Delta delta)
/* Nasopharyngeal port. */
delta -> tube [65]. Dyeq = f * (18 - 25 * art -> art [(int) kArt_muscle::LEVATOR_PALATINI]); /* 4.40 */
delta -> tube [65]. Dyeq = f * (18 - 25 * art -> art [(int) kArt_muscle::LEVATOR_PALATINI]); // 4.40
for (itube = 1; itube <= delta -> numberOfTubes; itube ++) {
for (integer itube = 1; itube <= delta -> numberOfTubes; itube ++) {
Delta_Tube t = delta -> tube + itube;
t -> s1 = 5e6 * t -> Dxeq * t -> Dzeq;
t -> s3 = t -> s1 / (0.9e-3 * 0.9e-3);
......
/* Speaker_to_Delta.cpp
*
* Copyright (C) 1992-2005,2006,2011,2015-2017 Paul Boersma
* Copyright (C) 1992-2005,2006,2011,2015-2018 Paul Boersma
*
* This code is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -24,7 +24,6 @@
autoDelta Speaker_to_Delta (Speaker me) {
double f = my relativeSize * 1e-3; // we shall use millimetres and grams
double xe [30], ye [30], xi [30], yi [30], xmm [30], ymm [30], dx, dy;
int closed [40];
autoDelta thee = Delta_create (89);
Melder_assert (my cord.numberOfMasses == 1 || my cord.numberOfMasses == 2 || my cord.numberOfMasses == 10);
......@@ -212,6 +211,7 @@ autoDelta Speaker_to_Delta (Speaker me) {
}
/* Vocal tract from neutral articulation. */
bool closed [40];
{
autoArt art = Art_create ();
Art_Speaker_meshVocalTract (art.get(), me, xi, yi, xe, ye, xmm, ymm, closed);
......
/* KNN.cpp
*
* Copyright (C) 2008 Ola So"der, 2010-2012,2016,2017 Paul Boersma
* Copyright (C) 2008 Ola So"der, 2010-2012,2016-2018 Paul Boersma
*
* This code is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -382,7 +382,7 @@ autoTableOfReal KNN_classifyToTableOfReal
int nthreads = KNN_getNumberOfCPUs();
integer chunksize = ps->ny / nthreads;
autoCategories uniqueCategories = Categories_selectUniqueItems (my output.get());
integer ncategories = Categories_getSize (uniqueCategories.get());
integer ncategories = uniqueCategories->size;
Melder_assert (nthreads > 0);
Melder_assert (ncategories > 0);
......@@ -408,7 +408,7 @@ autoTableOfReal KNN_classifyToTableOfReal
autoTableOfReal output = TableOfReal_create(ps->ny, ncategories);
for (integer i = 1; i <= ncategories; i ++)
TableOfReal_setColumnLabel (output.get(), i, SimpleString_c (uniqueCategories->at [i]));
TableOfReal_setColumnLabel (output.get(), i, uniqueCategories->at [i] -> string);
for (int i = 0; i < nthreads; i ++)
{
......@@ -467,78 +467,61 @@ void * KNN_classifyToTableOfRealAux
// Parameters //
///////////////////////////////
void * input
void * void_input
)
{
integer ncategories = Categories_getSize (((KNN_input_ToTableOfReal_t *) input)->uniqueCategories);
autoNUMvector <integer> indices ((integer) 0, ((KNN_input_ToTableOfReal_t *) input)->k);
autoNUMvector <double> distances ((integer) 0, ((KNN_input_ToTableOfReal_t *) input)->k);
for (integer y = ((KNN_input_ToTableOfReal_t *) input)->istart; y <= ((KNN_input_ToTableOfReal_t *) input)->istop; ++y)
{
KNN_kNeighbours(((KNN_input_ToTableOfReal_t *) input)->ps,
((KNN_input_ToTableOfReal_t *) input)->me->input.get(),
((KNN_input_ToTableOfReal_t *) input)->fws, y,
((KNN_input_ToTableOfReal_t *) input)->k, indices.peek(), distances.peek());
KNN_input_ToTableOfReal_t *input = (KNN_input_ToTableOfReal_t *) void_input;
integer ncategories = input -> uniqueCategories->size;
autoNUMvector <integer> indices ((integer) 0, input -> k);
autoNUMvector <double> distances ((integer) 0, input -> k);
for (integer i = 0; i < ((KNN_input_ToTableOfReal_t *) input)->k; ++i)
{
for (integer j = 1; j <= ncategories; ++j) {
if (FeatureWeights_areFriends (((KNN_input_ToTableOfReal_t *) input) -> me -> output->at [indices [i]],
((KNN_input_ToTableOfReal_t *) input) -> uniqueCategories->at [j]))
{
++((KNN_input_ToTableOfReal_t *) input) -> output -> data [y] [j];
for (integer y = input -> istart; y <= input -> istop; y ++) {
KNN_kNeighbours (input -> ps, input -> me -> input.get(), input -> fws, y, input -> k, indices.peek(), distances.peek());
for (integer i = 0; i < input -> k; i ++) {
for (integer j = 1; j <= ncategories; j ++) {
if (FeatureWeights_areFriends (input -> me -> output->at [indices [i]], input -> uniqueCategories->at [j])){
input -> output -> data [y] [j] += 1.0;
}
}
}
}
switch (((KNN_input_ToTableOfReal_t *) input)->dist)
{
switch (input -> dist) {
case kOla_DISTANCE_WEIGHTED_VOTING:
for (integer y = ((KNN_input_ToTableOfReal_t *) input) -> istart; y <= ((KNN_input_ToTableOfReal_t *) input) -> istop; y ++)
{
for (integer y = input -> istart; y <= input -> istop; y ++) {
real80 sum = 0.0;
for (integer c = 1; c <= ncategories; c ++)
{
((KNN_input_ToTableOfReal_t *) input)->output->data[y][c] *= 1 / OlaMAX(distances[c], kOla_MINFLOAT);
sum += ((KNN_input_ToTableOfReal_t *) input)->output->data[y][c];
for (integer c = 1; c <= ncategories; c ++) {
input -> output -> data [y] [c] *= 1.0 / OlaMAX (distances [c], kOla_MINFLOAT);
sum += input -> output -> data [y] [c];
}
for (integer c = 1; c <= ncategories; c ++) {
input -> output -> data [y] [c] /= sum;
}
for (integer c = 1; c <= ncategories; c ++)
((KNN_input_ToTableOfReal_t *) input)->output->data[y][c] /= sum;
}
break;
case kOla_SQUARED_DISTANCE_WEIGHTED_VOTING:
for (integer y = ((KNN_input_ToTableOfReal_t *) input)->istart; y <= ((KNN_input_ToTableOfReal_t *) input)->istop; ++y)
{
for (integer y = input -> istart; y <= input -> istop; y ++) {
real80 sum = 0.0;
for (integer c = 1; c <= ncategories; c ++)
{
((KNN_input_ToTableOfReal_t *) input)->output->data[y][c] *= 1 / OlaMAX(OlaSQUARE(distances[c]), kOla_MINFLOAT);
sum += ((KNN_input_ToTableOfReal_t *) input)->output->data[y][c];
for (integer c = 1; c <= ncategories; c ++) {
input -> output -> data [y] [c] *= 1.0 / OlaMAX (OlaSQUARE (distances [c]), kOla_MINFLOAT);
sum += input -> output -> data [y] [c];
}
for (integer c = 1; c <= ncategories; c ++) {
input -> output -> data [y] [c] /= sum;
}
for (integer c = 1; c <= ncategories; c ++)
((KNN_input_ToTableOfReal_t *) input)->output->data[y][c] /= sum;
}
break;
case kOla_FLAT_VOTING:
for (integer y = ((KNN_input_ToTableOfReal_t *) input)->istart; y <= ((KNN_input_ToTableOfReal_t *) input)->istop; ++y)
{
for (integer y = input -> istart; y <= input -> istop; y ++) {
real80 sum = 0.0;
for (integer c = 1; c <= ncategories; c ++)
sum += ((KNN_input_ToTableOfReal_t *) input)->output->data[y][c];
for (integer c = 1; c <= ncategories; c ++)
((KNN_input_ToTableOfReal_t *) input)->output->data[y][c] /= sum;
for (integer c = 1; c <= ncategories; c ++) {
sum += input -> output -> data [y] [c];
}
for (integer c = 1; c <= ncategories; c ++) {
input -> output -> data [y] [c] /= sum;
}
}
}
return nullptr;
}
......
......@@ -39,7 +39,7 @@ integer KNN_prune_prune
)
{
autoCategories uniqueCategories = Categories_selectUniqueItems (my output.get());
if (Categories_getSize (uniqueCategories.get()) == my nInstances)
if (uniqueCategories->size == my nInstances)
return 0;
integer removals = 0;
integer ncandidates = 0;
......
praat (6.0.38-1) unstable; urgency=medium
* New upstream version 6.0.38
* d/copyright: Reflect upstream changes
* d/control: Bump Standards-Version to 4.1.4
* d/p/fix-procrustes-unit-test.patch: New patch
* d/rules:
+ Remove the obsolete get-orig-source target
+ Honor nocheck in DEB_BUILD_OPTIONS
-- Rafael Laboissiere <rafael@debian.org> Sun, 08 Apr 2018 18:50:52 -0300
praat (6.0.37-2) unstable; urgency=medium
* d/t/run-tests: Drop unit tests that fail on s390x (Closes: #889703)
......
......@@ -11,7 +11,7 @@ Build-Depends: debhelper (>= 11),
xauth,
xvfb,
xmlto
Standards-Version: 4.1.3
Standards-Version: 4.1.4
Vcs-Browser: https://anonscm.debian.org/cgit/debian-med/praat.git
Vcs-Git: https://anonscm.debian.org/git/debian-med/praat.git
Homepage: http://www.praat.org
......
......@@ -5,7 +5,7 @@ Source: http://www.fon.hum.uva.nl/praat/download_sources.html
Files: *
Copyright: 1990-2018 Paul Boersma
1992-2017 David Weenink
1992-2018 David Weenink
2007 Erez Volk
2002 Hansjoerg Mixdorff
2008, 2017 Stefan de Konink
......
Description: Fix precision of unit test in test_Procrustes.praat
Author: Rafael Laboissiere <rafael@debian.org>
Forwarded: no
Last-Update: 2018-04-08
--- praat-6.0.38.orig/dwtest/test_Procrustes.praat
+++ praat-6.0.38/dwtest/test_Procrustes.praat
@@ -104,7 +104,7 @@ procedure test_procrustes_random_configu
Rename: "X_Yi"
# no need to test the translations, they need not be equal (see BG page 347)
.sp = Get scale
- assert abs(.scale - .sp) < .eps; '.scale' '.sp'
+ assert abs(.scale - .sp) < 10^4 * .eps; '.scale' '.sp'
removeObject: .c_x, .c_y, .c_z, .p_xy, .p_xy_i
endfor
use-ldflags.patch
remove-time-date-macros.patch
fix-procrustes-unit-test.patch
......@@ -86,8 +86,8 @@ override_dh_auto_install:
dh_installchangelogs debian/What_s_new_.html
dh_auto_install -- INSTALL=
ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
override_dh_auto_test:
PRAAT=$(CURDIR)/praat debian/tests/run-tests
endif
get-orig-source:
uscan --verbose --force-download --repack-compression xz
/* Collection_extensions.cpp
*
* Copyright (C) 1994-2011, 2015-2017 David Weenink
* Copyright (C) 1994-2011,2015-2017 David Weenink, 2018 Paul Boersma
*
* This code is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -26,7 +26,6 @@
*/
#include "Collection_extensions.h"
#include "Simple_extensions.h"
#include "NUM2.h"
autoCollection Collection_Permutation_permuteItems (Collection me, Permutation him) {
......@@ -76,16 +75,7 @@ autoCollection Collection_permuteItems (Collection me) {
/****************** class OrderedOfString ******************/
void structOrderedOfString :: v_info () {
structDaata :: v_info ();
MelderInfo_writeLine (U"Number of strings: ", our size);
autoOrderedOfString uStrings = OrderedOfString_selectUniqueItems (this);
MelderInfo_writeLine (U"Number of unique categories: ", uStrings->size); // FIXME: "categories"?, and why mention a Set property?
}
Thing_implement (OrderedOfString, Ordered, 0);
int OrderedOfString_append (OrderedOfString me, const char32 *append) {
int OrderedOfString_append (StringList me, const char32 *append) {
try {
if (! append) {
return 1; // BUG: lege string appenden??
......@@ -98,94 +88,62 @@ int OrderedOfString_append (OrderedOfString me, const char32 *append) {
}
}
autoOrderedOfString OrderedOfString_joinItems (OrderedOfString me, OrderedOfString thee) {
autoStringList OrderedOfString_joinItems (StringList me, StringList thee) {
try {
if (my size != thy size) {
Melder_throw (U"sizes should be equal.");
}
autoOrderedOfString him = Data_copy (me);
autoStringList him = Data_copy (me); // FIXME: this copies *all* the data from me, and only the strings from thee
for (integer i = 1; i <= my size; i ++) {
SimpleString_append (his at [i], thy at [i]);
SimpleString hisCategory = his at [i], thyCategory = thy at [i];
integer hisLength = str32len (hisCategory -> string), thyLength = str32len (thyCategory -> string);
hisCategory -> string = (char32 *) Melder_realloc (hisCategory -> string, (hisLength + thyLength + 1) * (integer) sizeof (char32));
str32cpy (& hisCategory -> string [hisLength], thyCategory -> string);
}
return him;
} catch (MelderError) {
Melder_throw (U"Items not joinmed.");
Melder_throw (U"Items not joined.");
}
}
autoOrderedOfString OrderedOfString_selectUniqueItems (OrderedOfString me) {
autoStringSet StringList_to_StringSet (StringList me) {
try {
autoStringSet thee = StringSet_create ();
autoStringSet you = StringSet_create ();
for (integer i = 1; i <= my size; i ++) {
if (! thy hasItem (my at [i])) { // FIXME: first sort, then unicize
autoSimpleString item = Data_copy (my at [i]);
thy addItem_move (item.move());
}
autoSimpleString item = SimpleString_create (my at [i] -> string);
your addItem_unsorted_move (item.move());
}
autoOrderedOfString him = OrderedOfString_create ();
for (integer i = 1; i <= thy size; i ++) {
autoSimpleString item = Data_copy (thy at [i]);
his addItem_move (item.move());
}
return him;
your sort ();
your unicize ();
return you;
} catch (MelderError) {
Melder_throw (me, U": unique items not selected.");
}
}
void OrderedOfString_frequency (OrderedOfString me, OrderedOfString thee, integer *count) {
for (integer i = 1; i <= my size; i ++) {
for (integer j = 1; j <= thy size; j ++) {
if (Data_equal (my at [i], thy at [j])) {
count[j]++;
break;
}
}
Melder_throw (me, U": not converted to StringSet.");
}
}
integer OrderedOfString_getNumberOfDifferences (OrderedOfString me, OrderedOfString thee) {
integer OrderedOfString_getNumberOfDifferences (StringList me, StringList thee) {
integer numberOfDifferences = 0;
if (my size != thy size) {
return -1;
return -1; // FIXME: this is arbitrary and unexpected
}
for (integer i = 1; i <= my size; i ++) {
if (! Data_equal (my at [i], thy at [i])) {
if (! Data_equal (my at [i], thy at [i])) { // FIXME: this compares all the data, instead of just the strings
numberOfDifferences ++;
}
}
return numberOfDifferences;
}
double OrderedOfString_getFractionDifferent (OrderedOfString me, OrderedOfString thee) {
double OrderedOfString_getFractionDifferent (StringList me, StringList thee) {
integer numberOfDifferences = OrderedOfString_getNumberOfDifferences (me, thee);
if (numberOfDifferences < 0) {
return undefined;
}
return my size == 0 ? 0.0 : (0.0 + numberOfDifferences) / my size;
return my size == 0 ? 0.0 : (double) numberOfDifferences / my size;
}
int OrderedOfString_difference (OrderedOfString me, OrderedOfString thee, integer *ndif, double *fraction) {
*ndif = 0;
*fraction = 1.0;
if (my size != thy size) {
Melder_flushError (U"OrderedOfString_difference: the numbers of items differ");
return 0;
}
for (integer i = 1; i <= my size; i ++) {
if (! Data_equal (my at [i], thy at [i])) {
(*ndif) ++;
}
}
*fraction = *ndif;
*fraction /= my size;
return 1;
}
integer OrderedOfString_indexOfItem_c (OrderedOfString me, const char32 *str) {
integer OrderedOfString_indexOfItem_c (StringList me, const char32 *str) {
integer index = 0;
autoSimpleString s = SimpleString_create (str);
......@@ -198,17 +156,13 @@ integer OrderedOfString_indexOfItem_c (OrderedOfString me, const char32 *str) {
return index;
}
const char32 *OrderedOfString_itemAtIndex_c (OrderedOfString me, integer index) {
return index > 0 && index <= my size ? SimpleString_c (my at [index]) : nullptr;
}
void OrderedOfString_initWithSequentialNumbers (OrderedOfString me, integer n) {
void OrderedOfString_initWithSequentialNumbers (StringList me, integer n) {
for (integer i = 1; i <= n; i ++) {
my addItem_move (SimpleString_create (Melder_integer (i)));
}
}
void OrderedOfString_changeStrings (OrderedOfString me, char32 *search, char32 *replace, int maximumNumberOfReplaces, integer *nmatches, integer *nstringmatches, bool use_regexp) {
void OrderedOfString_changeStrings (StringList me, char32 *search, char32 *replace, int maximumNumberOfReplaces, integer *nmatches, integer *nstringmatches, bool use_regexp) {
regexp *compiled_search = nullptr;
try {
Melder_require (search, U"The search string should not be empty.");
......@@ -241,7 +195,7 @@ void OrderedOfString_changeStrings (OrderedOfString me, char32 *search, char32 *
}
}
integer OrderedOfString_isSubsetOf (OrderedOfString me, OrderedOfString thee, integer *translation) { // ?? test and give number
integer OrderedOfString_isSubsetOf (StringList me, StringList thee, integer *translation) { // ?? test and give number
integer nStrings = 0;
for (integer i = 1; i <= my size; i ++) {
......@@ -259,17 +213,7 @@ integer OrderedOfString_isSubsetOf (OrderedOfString me, OrderedOfString thee, in
return nStrings;
}
void OrderedOfString_drawItem (OrderedOfString me, Graphics g, integer index, double xWC, double yWC) {
if (index > 0 && index <= my size) {
SimpleString_draw (my at [index], g, xWC, yWC);
}
}
integer OrderedOfString_getSize (OrderedOfString me) {
return my size;
}
void OrderedOfString_removeOccurrences (OrderedOfString me, const char32 *search, bool use_regexp) {
void OrderedOfString_removeOccurrences (StringList me, const char32 *search, bool use_regexp) {
if (! search) {
return;
}
......
......@@ -2,7 +2,7 @@
#define _Collection_extensions_h_
/* Collection_extensions.h
*
* Copyright (C) 1994-2017 David Weenink, 2015 Paul Boersma
* Copyright (C) 1994-2017 David Weenink, 2015,2018 Paul Boersma
*
* This code is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -27,45 +27,27 @@ autoCollection Collection_Permutation_permuteItems (Collection me, Permutation h
autoCollection Collection_permuteItems (Collection me);
/* permute the order of my items */
/****************** class OrderedOfString ******************/
int OrderedOfString_append (StringList me, const char32 *append);
Collection_define (OrderedOfString, OrderedOf, SimpleString) {
void v_info ()
override;
};
int OrderedOfString_append (OrderedOfString me, const char32 *append);
autoOrderedOfString OrderedOfString_joinItems (OrderedOfString me, OrderedOfString thee);
autoStringList OrderedOfString_joinItems (StringList me, StringList thee);
/* Join each item */
autoOrderedOfString OrderedOfString_selectUniqueItems (OrderedOfString me);
/* Postcondition: thy size <= my size */
void OrderedOfString_frequency (OrderedOfString me, OrderedOfString thee, integer *count);
/* count how often the items in 'thee' occur in 'me' */
/* Precondition: count[1..thy size] exists */
autoStringSet StringList_to_StringSet (StringList me);
/* To be removed Praat 4.2.4 2004040427 */
int OrderedOfString_difference (OrderedOfString me, OrderedOfString thee, integer *ndif, double *fraction);
double OrderedOfString_getFractionDifferent (StringList me, StringList thee);
double OrderedOfString_getFractionDifferent (OrderedOfString me, OrderedOfString thee);
integer OrderedOfString_getNumberOfDifferences (StringList me, StringList thee);
integer OrderedOfString_getNumberOfDifferences (OrderedOfString me, OrderedOfString thee);
integer OrderedOfString_indexOfItem_c (StringList me, const char32 *str);
const char32 *OrderedOfString_itemAtIndex_c (OrderedOfString me, integer index);
integer OrderedOfString_indexOfItem_c (OrderedOfString me, const char32 *str);
void OrderedOfString_initWithSequentialNumbers (StringList me, integer n);
void OrderedOfString_drawItem (OrderedOfString me, Graphics g, integer index, double xWC, double yWC);
void OrderedOfString_removeOccurrences (StringList me, const char32 *search, bool use_regexp);
void OrderedOfString_initWithSequentialNumbers (OrderedOfString me, integer n);
void OrderedOfString_removeOccurrences (OrderedOfString me, const char32 *search, bool use_regexp);
void OrderedOfString_changeStrings (OrderedOfString me, char32 *search, char32 *replace,
void OrderedOfString_changeStrings (StringList me, char32 *search, char32 *replace,
int maximumNumberOfReplaces, integer *nmatches, integer *nstringmatches, bool use_regexp);
integer OrderedOfString_isSubsetOf (OrderedOfString me, OrderedOfString thee, integer *translation);
integer OrderedOfString_isSubsetOf (StringList me, StringList thee, integer *translation);
/* Check whether my items are (a subset of)|(in) thy items.
* Preconditions:
* if (translation) translation[1..my size] exists.
......@@ -76,7 +58,4 @@ integer OrderedOfString_isSubsetOf (OrderedOfString me, OrderedOfString thee, in
* else if (translation[i] == 0) my label[i] not in thy labels.
*/
integer OrderedOfString_getSize (OrderedOfString me);
/* return my size */
#endif /* _Collection_extensions_h_ */